├── CODEOWNERS ├── LICENSE ├── README.md ├── SECURITY.md ├── andriod ├── adb_ls.sh ├── adb_pull.sh ├── adb_push.sh ├── adb_rm.sh ├── adb_shell.sh ├── adb_ss.sh ├── adb_wifi.sh ├── airplane_mode.sh ├── alias.sh ├── busybox_setup.txt ├── cron.sh ├── drain_power.sh ├── phone_settings.sh ├── phone_status.sh ├── remove_bloatware.sh └── send_sms.sh ├── awk ├── README.md ├── awk_sample.awk ├── client_access_entry.awk ├── create_html_table.awk ├── fw_drop_report.awk └── google_contact_to_callcentric.awk ├── car ├── README.md └── tesla │ ├── README.md │ ├── tesla.sh │ └── tesla_token.sh ├── check_install.sh ├── docker-jitsi ├── docker-compose.yml ├── env.selvans.net ├── jitsi.sh ├── jitsi_user.sh ├── jitsi_user_reset.sh ├── meet.selvans.net.conf └── selvans.net_watermark.png ├── docker-scripts ├── docker.sh ├── docker_list_containerid.sh ├── docker_registry_cleaner.sh ├── docker_registry_prune.sh ├── docker_sysctl_tuning.conf └── swarm_monitor.sh ├── firebase ├── .gitignore └── selvans-dynamic-links │ ├── .firebaserc │ ├── .gitignore │ ├── README.txt │ ├── firebase.json │ └── public │ ├── 404.html │ └── index.html ├── firewall ├── README.md ├── firewall ├── firewall_install.sh └── pf_rules_simple.conf ├── freestyle-libre ├── README.md ├── liapp_gdrive_import.sh ├── libre-db-empty.sqlite ├── libre_app.pl └── libre_view_import.sh ├── googleapps_scripts ├── DeleteTmp.gs └── README.md ├── googlehome_scripts ├── AllLights.yaml ├── BedroomLights.yaml ├── BedroomTV.yaml ├── BedsideLamps.yaml ├── Doorbell.yaml ├── FrenchPressTimer.yaml ├── Garage.yaml ├── Home-Away.yaml ├── KitchenLight.yaml ├── LivingroomLights.yaml ├── PorchLights.yaml ├── ReminderAnnouncements.yaml ├── SleepTime.yaml ├── TVLighting.yaml └── TimeAnnounce.yaml ├── install.sh ├── iot └── kasa │ ├── README.md │ └── kasa.sh ├── java ├── java_installed_versions.sh └── jvm_oldgen.sh ├── linux ├── check_bash_vulnerability.sh ├── check_disks.sh ├── createSftpAccount.sh ├── dev_list.sh ├── dmesg.pl ├── drop_cache.sh ├── find_zmeu.sh ├── flush_iptables.sh ├── iptables_block_ms.sh ├── iptables_lb_fake.sh ├── linux_account.sh ├── max_capacity_change.sh ├── oom_score.sh ├── process_info.sh ├── process_mon.sh ├── rss_size.sh ├── service_connection_count.sh └── vfs_cache_pressure.sh ├── macos ├── README.md ├── ad_password_expiry.sh ├── auto_sshfs ├── bashrc ├── cleanup_cache.sh ├── crashplan.sh ├── cylance.sh ├── diskutil.sh ├── free_wifi.sh ├── freestyle_libre.sh ├── iso2bootable.sh ├── jamf.sh ├── keychain.sh ├── locate_updatedb.sh ├── logtune.sh ├── macos.sh ├── mount_sshfs.sh ├── msteam.sh ├── net.selvans.network_change.plist ├── net.selvans.network_change.sh ├── pa_trap_agent.sh ├── remove_launchd_items.sh ├── say.sh ├── smcFanReset.sh ├── spoof_mac.sh ├── spotlight.sh ├── sync_time.sh ├── sysctl.conf ├── sysctl_tune.sh ├── txt2mp3.sh ├── user.sh ├── vpns.sh ├── wifi_password.sh └── zap_zoom_ws.sh ├── misl ├── findmods.sh ├── graphic_perf.sh └── tesla_adapter_check.sh ├── pihole ├── README.md └── block_list.txt ├── python_modules ├── myutils.py └── myutils_test.py ├── qemu ├── README.qemu ├── entitlements.xml └── run_qemu.sh ├── raspberrypi ├── README.md ├── README.metasploit ├── README.opencanary ├── README.pibackup ├── README.raspberrypi ├── cmdline.txt ├── dhcpcd.conf ├── init_resize.sh ├── opencanary.conf ├── periodic_run.sh ├── pizero-logrotate ├── poweron_run.sh ├── root.crontab ├── wifi_event_run.sh └── wpa_supplicant.conf ├── router ├── asus-gt-ax11000 │ ├── asus_usbmount.sh │ └── howto.txt └── dhcp_leases.sh ├── security ├── README.md ├── certbot_renew.sh ├── clamscan.sh ├── deterministic_pwgen.sh ├── enc_account.sh ├── encrypted_drive.sh ├── gpg_backup.sh ├── ismalicious.sh ├── isphishing.sh ├── list_url_redirects.sh ├── mypass.sh ├── oathtool.sh ├── open_ports.sh ├── pwned_password.php ├── qrcode.sh ├── qrcode2txt.sh ├── rbl_check.sh ├── secret.sh ├── security.sh ├── ssl.sh ├── symantec_vipaccess_key.sh ├── veracrypt.sh └── vpnsecure │ ├── openvpn_down.sh │ ├── openvpn_up.sh │ ├── other_servers.txt │ ├── us_servers.txt │ └── vpnsecure.ovpn ├── ssl ├── create_dkim_key.sh └── rootCA_howto.txt ├── tools ├── LdapAuthenticator.php ├── ScanQRCode.php ├── ad2unix_time.sh ├── add_metadata.sh ├── add_ssh_pubkey.sh ├── apache_version_check.sh ├── archive.sh ├── audio2video.sh ├── check_modified.sh ├── cleanup_space.sh ├── copy_metadata.sh ├── create_thumbs.sh ├── create_timelapse.sh ├── create_videos.csv ├── create_videos.sh ├── curl_ws_run.sh ├── dedup.sh ├── disk_clone.sh ├── disk_copy.sh ├── dns_perf.sh ├── dnssec_check.sh ├── echo_webserver.sh ├── elapsed_duration.php ├── exif.sh ├── fat32_size.sh ├── gdrive_rsync.sh ├── geocode_media_files.sh ├── git.sh ├── git_migrate.sh ├── google_home_light.sh ├── gps_echo.py ├── http_cap.sh ├── human_time.sh ├── img2video.sh ├── jitter_max.sh ├── lottery_number.sh ├── media_type.sh ├── mount_blobfuse.sh ├── mount_s3.sh ├── mount_smb.sh ├── mount_ssh.sh ├── my_touch.sh ├── nef2jpg.sh ├── network.sh ├── node_version_check.sh ├── obi.sh ├── onedrive_rsync.sh ├── oui_lookup.sh ├── packet_loss.sh ├── peopledatalabs.sh ├── phone_home.sh ├── ping_test.sh ├── process.sh ├── ps.sh ├── rename_ext.sh ├── reset_directory_timestamp.sh ├── reset_file_timestamp.sh ├── reset_media_timestamp.sh ├── sftp.sh ├── show_hostinfo.sh ├── simple_rsync.sh ├── skype_bridge.sh ├── speedtest-cli.sh ├── speedtest-fast.sh ├── telnet_mailer.sh ├── testmynet_cli.sh ├── tls_check.php ├── tls_check.sh ├── travel_backup.sh ├── url_speedtest.sh ├── util.sh ├── vonage_vportal_reboot.sh ├── weekly_backup.sh ├── whois.sh ├── wifi_qrcode.png └── wifi_qrcode.sh ├── utils ├── functions.sh ├── logger.sh └── sample.sh └── wifi-sdcards ├── README.md └── transcend ├── README.md ├── access.sh ├── authorized_keys ├── autorun.sh ├── autorun_simple.sh ├── busybox-armv5l ├── dropbear_dss_host_key ├── dropbear_rsa_host_key ├── dropbearmulti-armv5l └── ntpd.sh /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # 2 | # CODEOWNERS 3 | # 4 | 5 | # default owner 6 | * @aselvan 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018-2023 Arul Selvan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | The repo is mainly made of shell scripts and I am not aware of any security vulnerability 6 | on any of them. 7 | 8 | Note: All script files committed in this repo are digitially signed by me with my key below. 9 | 10 | [PGP fingerprint: 272D 038D 3AA1 E240 0ECC 9FF7 9C75 DE35 451A 1B6C](http://biglumber.com/x/web?pk=272D038D3AA1E2400ECC9FF79C75DE35451A1B6C) 11 | 12 | | Version | Supported | 13 | | ------- | ------------------ | 14 | | All | :white_check_mark: | 15 | 16 | 17 | ## Reporting a Vulnerability 18 | 19 | If you find anything to report, please contact the maintainer directly. 20 | -------------------------------------------------------------------------------- /andriod/airplane_mode.sh: -------------------------------------------------------------------------------- 1 | #!/system/bin/sh 2 | # 3 | # turn on/off airplane mode 4 | # 5 | # Can be used in cron to turn off aiplane mode at night to avoid RF signal 6 | # transmission since phone is close to bedside. 7 | # 8 | # Author: Arul Selvan 9 | # Version: Dec 22, 2017 10 | # 11 | 12 | function usage() { 13 | echo "Usage: $0 |" 14 | exit 15 | } 16 | 17 | if [ $# -lt 1 ]; then 18 | usage 19 | fi 20 | 21 | if [ $1 = "on" ]; then 22 | echo "Turning on airplane mode" 23 | /system/bin/settings put global airplane_mode_on 1 24 | /system/bin/am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true 25 | elif [ $1 = "off" ]; then 26 | echo "Turning off airplane mode" 27 | /system/bin/settings put global airplane_mode_on 0 28 | /system/bin/am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true 29 | else 30 | echo "Unknown option: $1" 31 | usage 32 | fi 33 | -------------------------------------------------------------------------------- /andriod/alias.sh: -------------------------------------------------------------------------------- 1 | # 2 | # alias.sh --- script to source for handy alias on adb shell 3 | # 4 | # Author: Arul Selvan 5 | # Version: Sep 2017 6 | # 7 | # Note: see busybox_setup.txt in this directory to setup busybox first 8 | # 9 | export BB_HOME="/data/local/tmp" 10 | export PATH="$PATH:$BB_HOME" 11 | 12 | export SD_CARD="/sdcard" 13 | export CAM_DATA="$SD_CARD/DCIM/Camera" 14 | export MY_DATA="$SD_CARD/data" 15 | 16 | # misl alias for rooted android to make changes to system area i.e. remount rw 17 | alias system_rw='mount -o remount,rw /system' 18 | alias system_ro='mount -o remount,ro /system' 19 | 20 | # others 21 | alias myip='echo -n `wget -qO- ifconfig.me/ip`|xargs echo' 22 | alias ll='ls -l' 23 | alias battery='cat /sys/class/power_supply/battery/capacity' 24 | 25 | # note: vi stdin does not work on busybox so manually do vi after decrypting 26 | # supply the encrypted filename arg to dec alias ofcourse 27 | # note: remove -md md5 if you are not using macOS native openssl which uses LibreSSL 28 | # that is defaulting to md5 so other platform version of openssl will fail decrypting 29 | alias dec='openssl enc -d -aes-256-cbc -a -md md5 -in' 30 | -------------------------------------------------------------------------------- /andriod/busybox_setup.txt: -------------------------------------------------------------------------------- 1 | # 2 | # busybox_setup.sh --- notes to setup busy box on android adb shell 3 | # 4 | # Author: Arul Selvan 5 | # Version: Sep 2017 6 | # 7 | # Note: As of May 2022 (android 12) the /data/local/tmp is still is 8 | # writable for adb shell, so you can set executable bit to anything there. 9 | # 10 | # For busybox, download the binary from the link below and copy 11 | # to /data/local/tmp and install it as shown below to get all 12 | # unix commandline tools softlinked to busybox. 13 | # 14 | # How to setup busybox binary: 15 | # ---------------------------- 16 | # download: https://github.com/xerta555/Busybox-Binaries/raw/master/busybox-arm64 17 | # adb push busybox-arm64 /data/local/tmp/. 18 | # adb push alias.sh /data/local/tmp/. 19 | # adb shell 20 | # cd /data/local/tmp 21 | # chmod +x busybox-arm64 22 | # ./busybox-arm64 --install -s /data/local/tmp 23 | # 24 | # How to use busybox in adb shell: 25 | # -------------------------------- 26 | # Once you connect to adb shell, you can source this script to set 27 | # path to all busybox applets and few handy aliases. 28 | # 29 | # . /data/local/tmp/alias.sh' 30 | -------------------------------------------------------------------------------- /andriod/cron.sh: -------------------------------------------------------------------------------- 1 | # 2 | # cron.sh --- start cron 3 | # 4 | # Author: Arul Selvan 5 | # Version: Dec 20, 2017 6 | # 7 | # PreReq: see busybox_setup.txt in this directory to setup busybox first 8 | 9 | # set timezone here, though crontab has it as well. 10 | TZ=CST6CDT 11 | export TZ 12 | myid=`id -nu` 13 | name="cron.sh" 14 | 15 | # busybox location 16 | export BB_HOME="/data/local/tmp" 17 | export PATH="$PATH:$BB_HOME" 18 | CRON_HOME="$BB_HOME/cron.d/crontabs" 19 | 20 | function is_cron_running() { 21 | ps|grep crond >/dev/null 2>&1 22 | rc=$? 23 | if [ $rc -gt 0 ] ; then 24 | return 25 | fi 26 | # if we call it for just checking exit 27 | if [ -z $1 ] ; then 28 | log -p i -t $myid "$name: crond is already running ... exiting." 29 | exit 30 | fi 31 | log -p i -t $myid "$name: crond succesfully started." 32 | } 33 | 34 | # log something 35 | log -p i -t $myid "$name: starting ..." 36 | 37 | # start only if it is not running already 38 | log -p i -t $myid "$name: checking to see if crond is already running ..." 39 | is_cron_running 40 | 41 | # ensure crond home exists 42 | mkdir -p $CRON_HOME 43 | 44 | # start cron 45 | log -p i -t $myid "$name: enabling crond ..." 46 | crond -b -c $CRON_HOME 47 | 48 | # check to see if it is running now that we started above 49 | is_cron_running 1 50 | 51 | log -p i -t $myid "$name: done" 52 | 53 | # mark some variable 54 | setprop selvans.cron.active 1 55 | -------------------------------------------------------------------------------- /andriod/drain_power.sh: -------------------------------------------------------------------------------- 1 | #!/system/bin/sh 2 | 3 | # 4 | # Simple script to suck the battery out dry fast. 5 | # 6 | # Author: Arul Selvan 7 | # Version: Oct 18, 2017 8 | # 9 | # Note: the mmc0 device driver sucks power so fast so just do a repeted file read 10 | # to drian battery rapidly. First run 'cs' tool to disable charging and enable 11 | # when battery reaches 1% 12 | # 13 | # Note2: This cant be run in /sdcard/bin since it is not allowed to run from because 14 | # of noexec mount of sdcard. So copy it to /data/local/; chmod +x and then run 15 | # 16 | 17 | log_file=/sdcard/tmp/battery_drain.log 18 | battery_level=`cat /sys/class/power_supply/battery/capacity` 19 | 20 | echo "Battery drain start..." > $log_file 21 | echo "Battery Level: $battery_level" >> $log_file 22 | 23 | # disable charging 24 | echo 0 >/sys/class/power_supply/battery/charging_enabled 25 | 26 | while [ $battery_level -gt 1 ] ; do 27 | find / -name $battery_level >> /dev/null 2>&1 28 | battery_level=`cat /sys/class/power_supply/battery/capacity` 29 | echo "current battery level = $battery_level" >> $log_file 30 | echo "`date` : pausing for 2 sec ..." >> $log_file 31 | sleep 2 32 | done 33 | 34 | echo "battery drain done." >> $log_file 35 | echo "current battery level = `cat /sys/class/power_supply/battery/capacity`" >> $log_file 36 | 37 | # enable charging 38 | echo 1 >/sys/class/power_supply/battery/charging_enabled 39 | echo "Now battery should start charging..." >> $log_file 40 | -------------------------------------------------------------------------------- /andriod/send_sms.sh: -------------------------------------------------------------------------------- 1 | #!/system/bin/sh 2 | # 3 | # send sms 4 | # 5 | # Author: Arul Selvan 6 | # Version: Mar 31, 2018 7 | # 8 | 9 | function usage() { 10 | echo "Usage: $0 <+1number> " 11 | exit 12 | } 13 | 14 | if [ $# -lt 2 ]; then 15 | usage 16 | fi 17 | 18 | number=$1 19 | text=$2 20 | 21 | echo "Sending \"$text\" to $number ..." 22 | am start -a android.intent.action.SENDTO -d sms:$number --es sms_body "$text" --ez exit_on_sent true 23 | 24 | # wait for ui to bring up activity 25 | sleep 1 26 | 27 | # press key 22 (D-pad right) 28 | input keyevent 22 29 | sleep 1 30 | 31 | # NOTE: does not work with android messages which expects 32 | # position (x,y) and finger touch to send messages not enter key! 33 | 34 | # press key 66 (enter key) to send 35 | input keyevent 66 36 | -------------------------------------------------------------------------------- /awk/README.md: -------------------------------------------------------------------------------- 1 | # Old/random/useless awk script for reference 2 | 3 | ### Random awk scripts 4 | 5 | -------------------------------------------------------------------------------- /awk/awk_sample.awk: -------------------------------------------------------------------------------- 1 | # sample to show sprintf and sub function usage and color 2 | # sample run: echo "first second third" |awk -f awk_sample.awk 3 | BEGIN{} 4 | { 5 | red_color_on="\033[1;31m"; 6 | red_color_off="\033[0m"; 7 | name=$1; 8 | company=$2; 9 | score=trim($3); 10 | print "Plain: ",$1,$2,$3; 11 | print "Color: ",$1,$2, red_color_on $3 red_color_off; 12 | var = sprintf("%s => array(0 => %s, \"%s\"),",name,score,company); 13 | print var; 14 | } 15 | 16 | function trim(s) { 17 | sub(/\r/,"",s); 18 | return s; 19 | } 20 | -------------------------------------------------------------------------------- /awk/client_access_entry.awk: -------------------------------------------------------------------------------- 1 | # 2 | # Simple awk to get the pair of host/IP and create a line to include in 3 | # postfix client_access file 4 | # 5 | # Author: Arul Selvna 6 | # Version: Apr 14, 2012 7 | # 8 | 9 | BEGIN { 10 | rule_num=287; 11 | } 12 | { 13 | ip = $1; 14 | host= $2; 15 | rule_num=rule_num+1; 16 | print ip, " 554 No SPAM/UBE/opt-in accepted here, get lost -rule=",rule_num," [",host,"] [Rulename: client_access_cidr]"; 17 | } 18 | 19 | END { 20 | # print ""; 21 | } 22 | -------------------------------------------------------------------------------- /awk/create_html_table.awk: -------------------------------------------------------------------------------- 1 | # 2 | # create_html_table.awk 3 | # 4 | # Given a file of the form title=url on each line, this awk script will parse the 5 | # file and create a simple html file for a webserver to serve. 6 | # 7 | # sample run: cat | awk -f create_html_table.awk 8 | # 9 | # Author: Arul Selvan 10 | # Version: Apr 2, 2023 11 | # 12 | 13 | BEGIN { 14 | # the separator, can change to whatever separates title and url on each row 15 | FS = "="; 16 | 17 | # script version 18 | version = "create_html_table.awk v20230402"; 19 | url_link = "https://github.com/aselvan/scripts/blob/master/awk/create_html_table.awk"; 20 | 21 | # simple html header 22 | print ""; 23 | print " "; 24 | print ""; 25 | print ""; 26 | 27 | print "

Created by " version "
" ; 28 | print "SelvanSoft, LLC

"; 29 | 30 | # start table 31 | print " "; 32 | 33 | } 34 | 35 | { 36 | desc = trim($1); 37 | url = trim($2); 38 | 39 | # no name available, then skip 40 | if ( desc == "" || url == "" ) next; 41 | 42 | # write a row 43 | print ""; 44 | print " "; 45 | print " "; 46 | print ""; 47 | 48 | } 49 | 50 | function ltrim(s) { sub(/^[ \t\r\n]+/, "", s); return s } 51 | function rtrim(s) { sub(/[ \t\r\n]+$/, "", s); return s } 52 | function trim(s) { return rtrim(ltrim(s)); } 53 | 54 | END { 55 | # end table 56 | print "
" desc " " url "
"; 57 | print ""; 58 | print ""; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /awk/fw_drop_report.awk: -------------------------------------------------------------------------------- 1 | # 2 | # Simple awk to format the output of iptables command below 3 | # 4 | # 5 | # iptables -L ufw-user-input -n -v |grep DROP|sort -k1 -r -n|head -n10 6 | # header is: pkts bytes target prot opt in out source destination 7 | # 8 | # Author: Arul Selvna 9 | # Version: Jul 5, 2014 10 | # 11 | 12 | BEGIN { 13 | # any static stuff here 14 | print "#pkts\t#bytes\ttarget\tsource "; 15 | } 16 | { 17 | pkts = $1; 18 | bytes= $2; 19 | target=$3; 20 | source=$8; 21 | source_details=""; 22 | # only print if there are any packets 23 | if ( pkts > 0 ) { 24 | "whois "source" |grep descr|head -n1|awk -F: '{print $2;}'" | getline source_details 25 | if ( source_details == "") { 26 | "whois "source" |grep organisation| tail -n1|awk -F: '{print $2;}'" | getline source_details 27 | } 28 | # trim leading spaces 29 | sub(/^[ \t]+/, "", source_details) 30 | print pkts "\t" bytes "\t" target "\t" source " \t---> " source_details; 31 | } 32 | } 33 | 34 | END { 35 | # print ""; 36 | } 37 | -------------------------------------------------------------------------------- /awk/google_contact_to_callcentric.awk: -------------------------------------------------------------------------------- 1 | # 2 | # awk script to parse and pic google contact CSV file fields to be 3 | # imported into callcenter phone book which is very stupid simple 4 | # format: ,, , 5 | # 6 | # Need to get the following from Google contact CSV 7 | # $2 firstname 8 | # $4 lastname 9 | # $40 cell 10 | # $42 home 11 | # 12 | # sample run: cat | awk -f google_contact_to_callcentric.awk 13 | # 14 | # Author: Arul Selvan 15 | # Version: Nov 13, 2016 16 | # Version: Nov 13, 2021 17 | # 18 | # NOTE: This is not working because of multi-line issue. Changed the code to expect only 19 | # the needed columns name,cell,home by massaging (removing all columns) w/ Microsoft XL 20 | # Make sure run dos2unix since XL sticks in ^Ms, also run iconv to remove unicode chars 21 | # iconv -c -f utf-8 -t ascii contacts.csv > contacts.csv.nounicode 22 | # 23 | 24 | BEGIN { 25 | FS = ","; 26 | } 27 | { 28 | name = $1; 29 | cell = $2 30 | home = $3; 31 | 32 | # skip header 33 | if ( NR == 1 ) next; 34 | 35 | # no name available, then skip 36 | if ( name == "" ) next; 37 | 38 | # google export writes line feed for some address fields makeing 39 | # it two lines screwing with us. Still have to edit the output manually!!! 40 | # before we import to callcenter. 41 | # TODO: So bottomline is this not working because of multi-line, so use Excel for now!) 42 | 43 | # one line for home and cell 44 | if (home != "") { 45 | # call centric does not like phone formating, so strip it 46 | gsub(/-/, "", home); 47 | gsub(/\++/, "", home); 48 | gsub(/ /, "", home); 49 | gsub(/\(/, "", home); 50 | gsub(/\)/, "", home); 51 | print "," "\"" name "\"" "," home ; 52 | } 53 | 54 | if (cell != "") { 55 | # call centric does not like phone formating, so strip it 56 | gsub(/-/, "", cell); 57 | gsub(/\++/, "", cell); 58 | gsub(/ /, "", cell); 59 | gsub(/\(/, "", cell); 60 | gsub(/\)/, "", cell); 61 | print "," "\"" name "\"" "," cell ; 62 | } 63 | } 64 | 65 | END { 66 | # print ""; 67 | } 68 | -------------------------------------------------------------------------------- /car/README.md: -------------------------------------------------------------------------------- 1 | # car 2 | 3 | ### Misl tools/scripts for connected cars. 4 | 5 | - #### /tesla 6 | Scripts to control/access Tesla 7 | 8 | 9 | -------------------------------------------------------------------------------- /car/tesla/README.md: -------------------------------------------------------------------------------- 1 | # Tesla Tools 2 | 3 | ### Commandline tool to control/access your Tesla using Tesla's unofficial API. 4 | 5 | - #### /tesla.sh 6 | Main script to access various tesla commands. This script is tested on macOS and Linux. 7 | 8 | - #### /tesla_token.sh 9 | Script to get/refresh a bearer token for your car to use with all API calls using the tesls.sh script above. 10 | 11 | # Disclaimer 12 | This tesla scripts use Tesla's unofficial APIs i.e. https://owner-api.teslamotors.com/api/1, and comes without warranty of any kind what so ever. You are free to use it at your own risk. I assume no liability for the accuracy, correctness, completeness, or usefulness of any information provided by this scripts nor for any sort of damages using these scripts may cause. 13 | 14 | # Usage Guide 15 | 16 | #### Options 17 | 18 | ``` 19 | ./tesla.sh 20 | Usage: tesla.sh 21 | 22 | ``` 23 | 24 | #### Example 1 25 | ``` 26 | ./tesla.sh wakeup 27 | [INFO] attempting to wake up tesla... 28 | [INFO] tesla should be awake now. 29 | 30 | ``` 31 | 32 | #### Example 2 33 | ``` 34 | ./tesla.sh honk 35 | [INFO] attempting to wake up tesla... 36 | [INFO] tesla should be awake now. 37 | [INFO] executing 'POST' on route: https://owner-api.teslamotors.com/api/1/vehicles/xxxxxxxxxxx/command/honk_horn ... 38 | { 39 | "response": { 40 | "reason": "", 41 | "result": true 42 | } 43 | } 44 | 45 | ``` 46 | 47 | #### Example 3 48 | ``` 49 | ./tesla.sh lock 50 | [INFO] attempting to wake up tesla... 51 | [INFO] tesla should be awake now. 52 | [INFO] executing 'POST' on route: https://owner-api.teslamotors.com/api/1/vehicles/xxxxxxxxxx/command/door_lock ... 53 | { 54 | "response": { 55 | "reason": "", 56 | "result": true 57 | } 58 | } 59 | 60 | ``` 61 | -------------------------------------------------------------------------------- /check_install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # check_install.sh --- Check if scripts repo is installed. 4 | # 5 | # Validate the install directory and check necessary runtime environment 6 | # variables are available. This is only used in the brew tap formula at 7 | # link below. 8 | # 9 | # https://github.com/aselvan/homebrew-formulas/blob/master/Formula/aselvan-scripts.rb 10 | # 11 | # Author: Arul Selvan 12 | # Created: Jan 20, 2025 13 | # 14 | # Version History: 15 | # Jan 20, 2025 --- Initial version 16 | # 17 | 18 | # version format YY.MM.DD 19 | version=25.01.20 20 | 21 | default_scripts_github=$HOME/src/scripts.github 22 | scripts_github=${SCRIPTS_GITHUB:-$default_scripts_github} 23 | 24 | if [ ! -z "$scripts_github" ] && [ -d $scripts_github ] && [ -f $scripts_github/check_install.sh ] ; then 25 | echo "Scripts: Installed" 26 | exit 0 27 | else 28 | echo "Scripts: Not Installed" 29 | exit 1 30 | fi 31 | 32 | -------------------------------------------------------------------------------- /docker-jitsi/jitsi.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | # 3 | # jitsi.sh --- simple wrapper to setup directories, settings and start/stop jitsi docker service 4 | # 5 | # Note: change the lines where letsencrypt certs/keys are copied to your own keys 6 | # also change/customize/rename env.selvans.net to suite your needs, otherwise, 7 | # everything should work, and you'd be running jitsi video conf in your docker host 8 | # in under 10 minutes! 9 | # 10 | # Author: Arul Selvan 11 | # Version: May 30, 2020 12 | 13 | # domain name; used to reference letsencrypt path, env filename etc. 14 | my_domain=selvans.net 15 | 16 | # stop 17 | stop() { 18 | docker-compose down 19 | } 20 | 21 | # setup environment, password, ssl keys etc for the docker run 22 | setup() { 23 | # strong passwords for internal services 24 | JICOFO_COMPONENT_SECRET=`openssl rand -hex 16` 25 | JICOFO_AUTH_PASSWORD=`openssl rand -hex 16` 26 | JVB_AUTH_PASSWORD=`openssl rand -hex 16` 27 | JIGASI_XMPP_PASSWORD=`openssl rand -hex 16` 28 | JIBRI_RECORDER_PASSWORD=`openssl rand -hex 16` 29 | JIBRI_XMPP_PASSWORD=`openssl rand -hex 16` 30 | 31 | # cleanup the host configuration 32 | rm -rf ./configs 33 | mkdir -p configs/web/keys 34 | 35 | # copy you keys to config directory that is mapped as volume inside docker containers 36 | cp /etc/letsencrypt/live/$my_domain/fullchain.pem configs/web/keys/cert.crt 37 | cp /etc/letsencrypt/live/$my_domain/privkey.pem configs/web/keys/cert.key 38 | 39 | # copy the environment 40 | cp env.$my_domain .env 41 | 42 | # update the password on .env file 43 | sed -i.bak \ 44 | -e "s#JICOFO_COMPONENT_SECRET=.*#JICOFO_COMPONENT_SECRET=${JICOFO_COMPONENT_SECRET}#g" \ 45 | -e "s#JICOFO_AUTH_PASSWORD=.*#JICOFO_AUTH_PASSWORD=${JICOFO_AUTH_PASSWORD}#g" \ 46 | -e "s#JVB_AUTH_PASSWORD=.*#JVB_AUTH_PASSWORD=${JVB_AUTH_PASSWORD}#g" \ 47 | -e "s#JIGASI_XMPP_PASSWORD=.*#JIGASI_XMPP_PASSWORD=${JIGASI_XMPP_PASSWORD}#g" \ 48 | -e "s#JIBRI_RECORDER_PASSWORD=.*#JIBRI_RECORDER_PASSWORD=${JIBRI_RECORDER_PASSWORD}#g" \ 49 | -e "s#JIBRI_XMPP_PASSWORD=.*#JIBRI_XMPP_PASSWORD=${JIBRI_XMPP_PASSWORD}#g" \ 50 | "$(dirname "$0")/.env" 51 | } 52 | 53 | start() { 54 | # do the setup 55 | setup 56 | 57 | # stop just in case if it is running 58 | stop 59 | 60 | # start docker service 61 | docker-compose up -d 62 | } 63 | 64 | case $1 in 65 | start|stop) "$@" 66 | ;; 67 | *) echo "Usage: $0 " 68 | ;; 69 | esac 70 | 71 | -------------------------------------------------------------------------------- /docker-jitsi/jitsi_user.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | # 3 | # jitsi_user.sh --- simple wrapper to create delete prosody users for jitsi access 4 | # 5 | # Author: Arul Selvan 6 | # Version: May 30, 2020 7 | 8 | jitsi_host=meet.jitsi 9 | my_name=`basename $0` 10 | 11 | usage() { 12 | echo "Usage: $my_name [password]" 13 | exit 0 14 | } 15 | 16 | create() { 17 | user=$1 18 | password=$2 19 | if [ -z $user ] || [ -z $password ] ; then 20 | echo "[ERROR] 'user' and 'password' are required for create" 21 | usage 22 | fi 23 | docker-compose exec -T prosody prosodyctl --config /config/prosody.cfg.lua register $user $jitsi_host $password 24 | } 25 | 26 | delete() { 27 | user=$1 28 | if [ -z $user ] ; then 29 | echo "[ERROR] 'user' is a required argument for delete" 30 | usage 31 | fi 32 | docker-compose exec -T prosody prosodyctl --config /config/prosody.cfg.lua unregister $user $jitsi_host 33 | } 34 | 35 | update() { 36 | user=$1 37 | password=$2 38 | if [ -z $user ] || [ -z $password ] ; then 39 | echo "[ERROR] 'user' and 'password' are required for update" 40 | usage 41 | fi 42 | delete $user 43 | create $user $password 44 | } 45 | 46 | # first just do a ps in case stack is not running, it should start the stack 47 | docker ps >/tmp/jitsi_ps.txt 2>&1 48 | 49 | # create or delete users 50 | case $1 in 51 | create|delete|update) "$@" 52 | ;; 53 | *) 54 | usage 55 | ;; 56 | esac 57 | 58 | -------------------------------------------------------------------------------- /docker-jitsi/jitsi_user_reset.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | # 3 | # jitsi_user_reset.sh --- script to run under cron to reset users periodically 4 | # 5 | # Author: Arul Selvan 6 | # Version: Jun 26, 2020 7 | 8 | my_name=`basename $0` 9 | os_name=`uname -s` 10 | JITSI_HOME="/var/jitsi" 11 | 12 | # script to reset the password 13 | jitsi_user_script="$JITSI_HOME/jitsi_user.sh" 14 | 15 | # users list 16 | users_list_file="$JITSI_HOME/jitsi_users.txt" 17 | pwgen_bin="/usr/local/bin/pwgen" 18 | 19 | # need pwgen 20 | if [ $os_name != "Darwin" ]; then 21 | pwgen_bin="/usr/bin/pwgen" 22 | fi 23 | 24 | if [ ! -x $pwgen_bin ] ; then 25 | echo "[ERROR] missing required program '$pwgen_bin'" 26 | exit 27 | fi 28 | 29 | if [ -z "${CRED_PATH}" ] || [ ! -d "${CRED_PATH}" ] ; then 30 | echo "[ERROR] either CRED_PATH env variable is not set or not pointing to a valid directory!" 31 | exit 32 | fi 33 | 34 | if [ ! -x $jitsi_user_script ] ; then 35 | echo "[ERROR] missing required program '$jitsi_user_script'" 36 | exit 37 | fi 38 | 39 | # need users list 40 | if [ ! -f $users_list_file ] ; then 41 | echo "[ERROR] users list file '$users_list_file' missing..." 42 | usage 43 | else 44 | users_list=`cat $users_list_file` 45 | fi 46 | 47 | for user in $users_list ; do 48 | password=`$pwgen_bin 8 1` 49 | # just delete and add it back instead of update so non-existing users are created 50 | ( cd $JITSI_HOME ; $jitsi_user_script delete $user ) 51 | ( cd $JITSI_HOME ; $jitsi_user_script create $user $password ) 52 | echo "$password" > ${CRED_PATH}/$user.txt 53 | done 54 | -------------------------------------------------------------------------------- /docker-jitsi/meet.selvans.net.conf: -------------------------------------------------------------------------------- 1 | # 2 | # meet.selvans.net apache virtual reverse proxy conf 3 | # 4 | # note: jitsi runs under docker this is a definition of virtual host for 5 | # apache2 running on the docker host which is exposed to public internet. 6 | # Copy this file to the /etc/apache2/sites-enabled to reverse proxy the 7 | # the public request into the jitsi docker container. 8 | # 9 | # Author: Arul Selvan 10 | # Version: May 30, 2020 11 | # 12 | 13 | 14 | ServerName selvans.net 15 | ServerAlias meet.selvans.net 16 | ServerAdmin webmaster@selvans.net 17 | SSLEngine On 18 | SSLCertificateFile /etc/letsencrypt/live/selvans.net/cert.pem 19 | SSLCertificateKeyFile /etc/letsencrypt/live/selvans.net/privkey.pem 20 | SSLCACertificateFile /etc/letsencrypt/live/selvans.net/fullchain.pem 21 | 22 | # redirect to meet running under docker. 23 | SSLProxyEngine On 24 | SSLProxyVerify none 25 | SSLProxyCheckPeerCN off 26 | SSLProxyCheckPeerName off 27 | ProxyHTMLInterp On 28 | ProxyHTMLExtended On 29 | ProxyHTMLURLMap (.*)trex(.*) https://meet.selvans.net$2 [Rin] 30 | ProxyPass / https://trex:8443/ 31 | ProxyPassReverse / https://trex:8443/ 32 | 33 | # separate the logs 34 | CustomLog /var/log/apache2/meet-access.log combined 35 | ErrorLog /var/log/apache2/meet-error.log 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /docker-jitsi/selvans.net_watermark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aselvan/scripts/f4b81c8b4dcacd89f06f5b58a6bda1de5986d712/docker-jitsi/selvans.net_watermark.png -------------------------------------------------------------------------------- /docker-scripts/docker_list_containerid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # docker_list_containerid.sh 4 | # List all the container IDs (local and remote) for the swarm stack 5 | # 6 | # Author: Arul Selvan 7 | # Version: May 17, 2019 8 | # 9 | 10 | if [ -z $1 ] ; then 11 | echo "Usage: $0 " 12 | exit 13 | fi 14 | service_name=$1 15 | 16 | echo "[INFO] List of all containers across all hosts for the service '$service_name'" 17 | docker stack ps $service_name --format "{{.Node}} {{.ID}}" -f "desired-state=running"| while read entry ; do 18 | host=$(echo $entry | cut -f 1 -d " ") 19 | #if [ $host = $myhost ] ; then 20 | # continue 21 | #fi 22 | task=$(echo $entry | cut -f 2 -d " ") 23 | container=$(docker inspect --format '{{.Status.ContainerStatus.ContainerID}}' $task| head -c 12) 24 | echo "[INFO] remote container@host: ${container}@${host}" 25 | done 26 | 27 | -------------------------------------------------------------------------------- /docker-scripts/docker_registry_cleaner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Registry cleaner script. This is needed to purge and GC the registry that gets growing 4 | # in an uncontrollable way as CICD pipline builds happen every night for various products. 5 | # This script goes through each application namespace and collects all the image hashes 6 | # except the last recent X (controlled by image_count variable) and request API call to 7 | # delete the image. 8 | # 9 | # Note: this is run on cron every night to do daily cleanup 10 | # 11 | # Author: Arul Selvan 12 | # Version: Mar 21, 2018 13 | # 14 | 15 | registry_url="https://your.registry.com/v2" 16 | 17 | # leave just the last 12 images. 18 | image_count=12 19 | log_file=/tmp/docker_registry_cleaner.log 20 | rep_path=/data/docker_registry/docker/registry/v2/repositories 21 | 22 | echo "Registry cleaner start: `date`" > $log_file 23 | echo "$0 starting ..." >> $log_file 24 | 25 | # application list 26 | APP_LIST="vmp/fpm vmp/api ops/obc m1/app m1-reporting m1/m1-app-cron" 27 | 28 | for app_path in $APP_LIST ; do 29 | echo "Deleting namespace: $app_path" >> $log_file 30 | 31 | # check and make sure the dir exists 32 | if [ ! -d $rep_path/$app_path/_manifests/revisions/sha256/ ]; then 33 | echo " Nothing to delete for: $app_path" >> $log_file 34 | continue 35 | fi 36 | 37 | sha=$(ls -rt $rep_path/$app_path/_manifests/revisions/sha256/|head -n -$image_count) 38 | 39 | for hash in $sha; do 40 | echo " Deleting $hash ..." >> $log_file 41 | curl -s -X DELETE $registry_url/$app_path/manifests/sha256:$hash >> $log_file 2>&1 42 | done 43 | done 44 | 45 | # initiate registry GC process 46 | echo "" >> $log_file 47 | echo "Initiating registry GC process ... " >> $log_file 48 | docker exec registry /bin/registry garbage-collect /etc/docker/registry/config.yml >> $log_file 2>&1 49 | 50 | # need to restart registry (note: restart doesn't seem to work right, so stop and let systemd restart) 51 | docker stop registry 52 | sleep 15 53 | systemctl start registry 54 | -------------------------------------------------------------------------------- /docker-scripts/docker_registry_prune.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # prune docker registry with docker-distribution-pruner 4 | # pre_req: go get -u gitlab.com/gitlab-org/docker-distribution-pruner 5 | # 6 | # Note: this is run on cron once a week 7 | # 8 | # Author: Arul Selvan 9 | # Version: Oct 15, 2018 10 | # 11 | 12 | log_file=/tmp/docker_registry_prune.log 13 | rep_path=/data/docker_registry 14 | prune_tool=/opt/go/bin/docker-distribution-pruner 15 | prune_tool_options="-delete -soft-delete=false" 16 | docker_registry_config="/root/bin/docker_registry_config.yml" 17 | 18 | echo "Registry prune start: `date`" > $log_file 19 | echo "$0 starting ..." >> $log_file 20 | 21 | # run the prune tool 22 | if [ -x "$prune_tool" ] ; then 23 | $prune_tool -config=$docker_registry_config $prune_tool_options >> $log_file 2>&1 24 | else 25 | echo "$prune_tool is missing, exit" >> $log_file 26 | exit 27 | fi 28 | 29 | # initiate registry GC process (NOTE: not sure this is needed) 30 | echo "" >> $log_file 31 | echo "Initiating registry GC process ... " >> $log_file 32 | docker exec registry /bin/registry garbage-collect /etc/docker/registry/config.yml >> $log_file 2>&1 33 | 34 | # need to restart registry (NOTE: not sure this is needed) 35 | docker stop registry 36 | sleep 15 37 | systemctl start registry 38 | 39 | -------------------------------------------------------------------------------- /docker-scripts/docker_sysctl_tuning.conf: -------------------------------------------------------------------------------- 1 | # 2 | # docker related optimization 3 | # 4 | # Author: Arul Selvan 5 | # Version: Jul 17, 2019 6 | # 7 | # defaults are from CentOS 7.6 8 | 9 | 10 | # Have a larger connection range available; 11 | # TODO default:none 12 | net.ipv4.ip_local_port_range="1024 65000" 13 | 14 | # Reuse closed sockets faster; 15 | # TODO default:0 16 | net.ipv4.tcp_tw_reuse=1 17 | 18 | # reduce finwait; 19 | # TODO default:60 20 | net.ipv4.tcp_fin_timeout=15 21 | 22 | # The maximum number of "backlogged sockets"; 23 | # TODO default:128 24 | net.core.somaxconn=4096 25 | 26 | # max backlog 27 | # TODO default:1000 28 | net.core.netdev_max_backlog=4096 29 | 30 | # 16MB per socket - which sounds like a lot but will virtually never consume that much; 31 | # TODO default:212992 32 | net.core.rmem_max=16777216 33 | 34 | # TODO default:212992 35 | net.core.wmem_max=16777216 36 | 37 | # Various network tunables 38 | # TODO default:512 39 | net.ipv4.tcp_max_syn_backlog=20480 40 | 41 | # TODO default:65536 42 | net.ipv4.tcp_max_tw_buckets=400000 43 | 44 | # TODO default:0 45 | net.ipv4.tcp_no_metrics_save=1 46 | 47 | # TODO default: 4096 87380 6291456 48 | net.ipv4.tcp_rmem="4096 87380 16777216" 49 | # TODO default:6 50 | net.ipv4.tcp_syn_retries=2 51 | # TODO default:5 52 | net.ipv4.tcp_synack_retries=2 53 | # TODO default:4096 16384 4194304 54 | net.ipv4.tcp_wmem=4096 65536 16777216 55 | # OK default:67584 56 | #vm.min_free_kbytes=65536 57 | 58 | # Connection tracking to prevent dropped connections (usually issue on LBs) 59 | # OK default: 262144 60 | net.netfilter.nf_conntrack_max=262144 61 | # TODO default:none 62 | net.ipv4.netfilter.ip_conntrack_generic_timeout=120 63 | # OK: default:432000 64 | #net.netfilter.nf_conntrack_tcp_timeout_established=86400 65 | 66 | # ARP cache settings for a highly loaded docker swarm 67 | # OK default: 8192 68 | #net.ipv4.neigh.default.gc_thresh1=8096 69 | # OK default: 49152 70 | #net.ipv4.neigh.default.gc_thresh2=12288 71 | # OK default: 8192 72 | #net.ipv4.neigh.default.gc_thresh3=16384 73 | -------------------------------------------------------------------------------- /firebase/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | firebase-debug.log* 8 | firebase-debug.*.log* 9 | 10 | # Firebase cache 11 | .firebase/ 12 | 13 | # Firebase config 14 | 15 | # Uncomment this if you'd like others to create their own Firebase project. 16 | # For a team working on the same Firebase project(s), it is recommended to leave 17 | # it commented so all members can deploy to the same project(s) in .firebaserc. 18 | # .firebaserc 19 | 20 | # Runtime data 21 | pids 22 | *.pid 23 | *.seed 24 | *.pid.lock 25 | 26 | # Directory for instrumented libs generated by jscoverage/JSCover 27 | lib-cov 28 | 29 | # Coverage directory used by tools like istanbul 30 | coverage 31 | 32 | # nyc test coverage 33 | .nyc_output 34 | 35 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 36 | .grunt 37 | 38 | # Bower dependency directory (https://bower.io/) 39 | bower_components 40 | 41 | # node-waf configuration 42 | .lock-wscript 43 | 44 | # Compiled binary addons (http://nodejs.org/api/addons.html) 45 | build/Release 46 | 47 | # Dependency directories 48 | node_modules/ 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Optional REPL history 57 | .node_repl_history 58 | 59 | # Output of 'npm pack' 60 | *.tgz 61 | 62 | # Yarn Integrity file 63 | .yarn-integrity 64 | 65 | # dotenv environment variables file 66 | .env 67 | -------------------------------------------------------------------------------- /firebase/selvans-dynamic-links/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "selvans-dynamic-links": "selvans-dynamic-links", 4 | "default": "selvans-dynamic-links" 5 | }, 6 | "targets": {}, 7 | "etags": {} 8 | } 9 | -------------------------------------------------------------------------------- /firebase/selvans-dynamic-links/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | firebase-debug.log* 8 | firebase-debug.*.log* 9 | 10 | # Firebase cache 11 | .firebase/ 12 | 13 | # Firebase config 14 | 15 | # Uncomment this if you'd like others to create their own Firebase project. 16 | # For a team working on the same Firebase project(s), it is recommended to leave 17 | # it commented so all members can deploy to the same project(s) in .firebaserc. 18 | # .firebaserc 19 | 20 | # Runtime data 21 | pids 22 | *.pid 23 | *.seed 24 | *.pid.lock 25 | 26 | # Directory for instrumented libs generated by jscoverage/JSCover 27 | lib-cov 28 | 29 | # Coverage directory used by tools like istanbul 30 | coverage 31 | 32 | # nyc test coverage 33 | .nyc_output 34 | 35 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 36 | .grunt 37 | 38 | # Bower dependency directory (https://bower.io/) 39 | bower_components 40 | 41 | # node-waf configuration 42 | .lock-wscript 43 | 44 | # Compiled binary addons (http://nodejs.org/api/addons.html) 45 | build/Release 46 | 47 | # Dependency directories 48 | node_modules/ 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Optional REPL history 57 | .node_repl_history 58 | 59 | # Output of 'npm pack' 60 | *.tgz 61 | 62 | # Yarn Integrity file 63 | .yarn-integrity 64 | 65 | # dotenv environment variables file 66 | .env 67 | -------------------------------------------------------------------------------- /firebase/selvans-dynamic-links/README.txt: -------------------------------------------------------------------------------- 1 | README 2 | ====== 3 | To make changes to web app. The web app defined is just empty and does nothing 4 | but forward requests to link shortening. When changes are needed, just modify 5 | firebase.json as needed and do a deploy. 6 | 7 | Initial setup: 8 | ============= 9 | brew install firebase-tools 10 | 11 | Development steps: 12 | ================= 13 | 14 | * run 'firebase login' [if not installed or logged in already] 15 | * run 'firebase init' [select the correct project from cloud to work with] 16 | * make changes to firbase.json as needed, deploy static files, webapp etc to public/ dir etc 17 | * run 'firebase deploy' 18 | -------------------------------------------------------------------------------- /firebase/selvans-dynamic-links/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "ignore": [ 4 | "firebase.json", 5 | "**/.*", 6 | "**/node_modules/**" 7 | ], 8 | "appAssociation": "AUTO", 9 | "rewrites": [ 10 | { 11 | "source": "/**", 12 | "dynamicLinks": true 13 | } 14 | ] 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /firebase/selvans-dynamic-links/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page Not Found 7 | 8 | 23 | 24 | 25 |

26 |

404

27 |

Page Not Found

28 |

The specified file was not found on this website. Please check the URL for mistakes and try again.

29 |

Why am I seeing this?

30 |

This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.

31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /freestyle-libre/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Disclaimer 3 | This libre_app.pl script comes without warranty of any kind. Use it at your own risk. I assume no liability for the accuracy, correctness, completeness, or usefulness of any information provided by this scripts nor for any sort of damages using these scripts may cause. 4 | 5 | 6 | # Usage Guide 7 | 8 | #### Options 9 | 10 | ``` 11 | Usage: libre_app.pl [options] 12 | where options are: 13 | --import --type [libre=reader data; libreview=cloud export - default] 14 | --export 15 | --db 16 | --months 17 | --weeks 18 | --days 19 | --help usage 20 | --debug 1 print debug message 21 | 22 | ``` 23 | 24 | #### Example 1 25 | ``` 26 | ./libre_app.pl --days 14 27 | Opening DB: libre-db.sqlite 28 | Calculating A1C based on FreeStyle Libre CGM data... 29 | --- A1C going back to 14 days from 01/18/2020 11:11:32 AM --- 30 | Days Count Average SD CV A1C 31 | 14 98 116.93 20.45 17.49 5.70 32 | 13 49 130.39 27.03 20.73 6.17 33 | 12 88 99.42 20.79 20.92 5.09 34 | 11 104 112.96 25.02 22.15 5.56 35 | 10 102 104.34 17.46 16.73 5.26 36 | 9 109 103.58 14.35 13.86 5.24 37 | 8 80 100.60 19.05 18.94 5.13 38 | 7 99 102.99 22.25 21.61 5.22 39 | 6 92 109.39 12.26 11.21 5.44 40 | 5 97 105.68 25.39 24.03 5.31 41 | 4 84 102.27 19.60 19.16 5.19 42 | 3 92 105.38 29.67 28.15 5.30 43 | 2 96 103.99 22.03 21.18 5.25 44 | 1 61 99.89 18.84 18.86 5.11 45 | 46 | --- A1C for the entire period in the last 14 days --- 47 | Count Average SD CV A1C 48 | 1251 106.47 22.30 20.94 5.34 49 | ``` 50 | 51 | #### Example 2 52 | ``` 53 | ./libre_app.pl --weeks 4 54 | Opening DB: libre-db.sqlite 55 | Calculating A1C based on FreeStyle Libre CGM data... 56 | --- A1C going back to 4 weeks from 01/18/2020 11:11:41 AM --- 57 | Week Count Average SD CV A1C 58 | 4 557 116.08 22.55 19.43 5.67 59 | 3 552 119.59 24.16 20.20 5.79 60 | 2 582 104.25 20.47 19.64 5.26 61 | 1 522 104.75 22.30 21.29 5.28 62 | 63 | --- A1C for the entire period in the last 4 weeks --- 64 | Count Average SD CV A1C 65 | 2213 111.17 23.38 21.03 5.50 66 | ``` 67 | 68 | #### Example 3 69 | ``` 70 | ./libre_app.pl --months 3 71 | Opening DB: libre-db.sqlite 72 | Calculating A1C based on FreeStyle Libre CGM data... 73 | --- A1C by month starting with 3 months before to current --- 74 | Months Count Average SD CV A1C 75 | 3 2570 108.94 24.54 22.52 5.42 76 | 2 2564 118.37 23.50 19.85 5.75 77 | 1 2737 111.02 23.43 21.11 5.50 78 | 79 | --- A1C for the entire period in the last 3 months --- 80 | Count Average SD CV A1C 81 | 7871 112.73 24.15 21.42 5.56 82 | ``` 83 | -------------------------------------------------------------------------------- /freestyle-libre/libre-db-empty.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aselvan/scripts/f4b81c8b4dcacd89f06f5b58a6bda1de5986d712/freestyle-libre/libre-db-empty.sqlite -------------------------------------------------------------------------------- /freestyle-libre/libre_view_import.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # libre_view_import.sh --- handy script to import the librewview downloaded data 4 | # 5 | # Author: Arul Selvan 6 | # Version: May 17, 2020 7 | # 8 | 9 | log_dir="${HOME}/tmp" 10 | log_file="${log_dir}/libre_view_import.log" 11 | libre_app="./libre_app.pl" 12 | libre_export_file="libre_data_export.csv" 13 | libre_import_file="libreview_data.txt" 14 | 15 | # script must be in the libre-data (libre home direcory) 16 | scriptPath=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 17 | 18 | # go to libre-data directory 19 | cd $scriptPath || exit 20 | 21 | # make sure log dir exists 22 | mkdir -p $log_dir || exit 23 | 24 | download_file=$1 25 | 26 | if [ -z $download_file ]; then 27 | echo "Usage: $0 " 28 | exit 1 29 | fi 30 | 31 | # make sure the file exists 32 | if [ ! -f $download_file ]; then 33 | echo "Error: $download_file does not exist!" 34 | echo "Usage: $0 " 35 | exit 2 36 | fi 37 | 38 | # check and make sure our apps are available. 39 | if [ ! -e $libre_app ]; then 40 | echo "$libre_app program not found!" 41 | exit 42 | fi 43 | 44 | echo "Import libreview downloaded data from the file: $1 ..." > $log_file 45 | echo "Date: `date`">> $log_file 46 | 47 | # first backup DB 48 | cp libre-db.sqlite libre-db.sqlite.backup >>$log_file 2>&1 49 | 50 | $libre_app --import $download_file >>$log_file 2>&1 51 | if [ $? -ne 0 ] ; then 52 | echo "ERROR: importing, bailing out." 53 | exit 3 54 | fi 55 | 56 | # also export to our format 57 | cp $libre_export_file $libre_export_file.backup 58 | echo "Exporting to: $libre_export_file" >> $log_file 59 | $libre_app --export $libre_export_file >>$log_file 2>&1 60 | 61 | # make a backup of the $import_file and replace it w/ downloaded file 62 | if [ -f $libre_import_file ] ; then 63 | cp $libre_import_file $libre_import_file.backup 64 | mv $download_file $libre_import_file 65 | fi 66 | 67 | echo "$0 completed successfully." >>$log_file 2>&1 68 | -------------------------------------------------------------------------------- /googleapps_scripts/README.md: -------------------------------------------------------------------------------- 1 | # Google Apps Scripts 2 | 3 | ### Scripts for google app script platform 4 | 5 | - #### /DeleteTemp.cs 6 | This is a cron job like Google App Script to cleanup a dedicated temporary folder in gDrive. 7 | If the directories are 30 days or older, they are marked as 'trashed' so google can reclaim 8 | the space. This is typically used for files we share to other people and want to automatically 9 | delete them after sometime so they dont use up gDrive storage. 10 | 11 | -------------------------------------------------------------------------------- /googlehome_scripts/AllLights.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- All lights off w/ voice and at various time late night 3 | # Author: Arul Selvan 4 | # Version: Jun 25, 2023 5 | # 6 | metadata: 7 | name: All lights 8 | description: Turn off all lights w/ voice command and time based 9 | automations: 10 | - starters: 11 | - type: time.schedule 12 | at: 11:30 PM 13 | - type: time.schedule 14 | at: 12:30 AM 15 | - type: time.schedule 16 | at: 1:30 AM 17 | - type: assistant.event.OkGoogle 18 | eventData: query 19 | is: "all lights off" 20 | actions: 21 | - type: device.command.OnOff 22 | on: false 23 | devices: 24 | - b1 - Bedroom 25 | - b2 - Bedroom 26 | - b3 - Bedroom 27 | - b4 - Bedroom 28 | - bsl2 - Bedside 29 | - bsl - Bedside 30 | - lr1 - Living Room 31 | - lr2 - Living Room 32 | - lr3 - Living Room 33 | - lr4 - Living Room 34 | - u1 - Office 35 | - kl1 - Kitchen 36 | 37 | -------------------------------------------------------------------------------- /googlehome_scripts/BedroomLights.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- Bedroom light on or off w/ voice 3 | # Author: Arul Selvan 4 | # Version: Jun 16, 2023 5 | # 6 | metadata: 7 | name: Bedroom Lights 8 | description: Bedroom lights on or off at voice command. 9 | automations: 10 | - starters: 11 | - type: assistant.event.OkGoogle 12 | eventData: query 13 | is: "bedroom on" 14 | actions: 15 | - type: device.command.OnOff # Turn the device on or off. 16 | on: true 17 | devices: 18 | - b1 - Bedroom 19 | - b2 - Bedroom 20 | - b3 - Bedroom 21 | - b4 - Bedroom 22 | - starters: 23 | - type: time.schedule 24 | at: 11:30 PM 25 | - type: time.schedule 26 | at: 12:30 AM 27 | - type: time.schedule 28 | at: 1:30 AM 29 | - type: assistant.event.OkGoogle 30 | eventData: query 31 | is: "bedroom off" 32 | actions: 33 | - type: device.command.OnOff # Turn the device on or off. 34 | on: false 35 | devices: 36 | - b1 - Bedroom 37 | - b2 - Bedroom 38 | - b3 - Bedroom 39 | - b4 - Bedroom 40 | 41 | -------------------------------------------------------------------------------- /googlehome_scripts/BedroomTV.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- When bedroom TV on, ensure celing lights off and bedside lamps on 3 | # Author: Arul Selvan 4 | # Version: Jun 16, 2023 5 | # 6 | metadata: 7 | name: Bedroom TV 8 | description: When bedroom TV on, ensure lights off but bedside lamps on. 9 | automations: 10 | starters: 11 | type: device.state.OnOff 12 | state: on 13 | is: true 14 | device: TV 15 | condition: 16 | type: time.between 17 | after: sunset+30min 18 | before: sunrise 19 | actions: 20 | - type: device.command.OnOff 21 | on: false 22 | devices: 23 | - b1 - Bedroom 24 | - b2 - Bedroom 25 | - b3 - Bedroom 26 | - b4 - Bedroom 27 | - type: device.command.OnOff 28 | on: true 29 | devices: 30 | - bsl2 - Bedside 31 | - bsl - Bedside 32 | 33 | -------------------------------------------------------------------------------- /googlehome_scripts/BedsideLamps.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- Bedside lamp on or off at dawn/dusk & also w/ voice 3 | # Author: Arul Selvan 4 | # Version: Jun 16, 2023 5 | # 6 | metadata: 7 | name: Bedside Lamps 8 | description: Bedside lamp on (or off) at dawn/dusk as well as with voice command. 9 | automations: 10 | - starters: 11 | - type: time.schedule 12 | at: sunset-15min 13 | - type: assistant.event.OkGoogle 14 | eventData: query 15 | is: "bedside on" 16 | - type: assistant.event.OkGoogle 17 | eventData: query 18 | is: "lamp on" 19 | actions: 20 | - type: device.command.OnOff # Turn the device on or off. 21 | on: true 22 | devices: 23 | - bsl - Bedside 24 | - bsl2 - Bedside 25 | - starters: 26 | - type: assistant.event.OkGoogle 27 | eventData: query 28 | is: "bedside off" 29 | - type: assistant.event.OkGoogle 30 | eventData: query 31 | is: "lamp off" 32 | - type: time.schedule 33 | at: 11:30 PM 34 | - type: time.schedule 35 | at: 12:30 AM 36 | - type: time.schedule 37 | at: 1:30 AM 38 | actions: 39 | - type: device.command.OnOff # Turn the device on or off. 40 | on: false 41 | devices: 42 | - bsl - Bedside 43 | - bsl2 - Bedside 44 | 45 | -------------------------------------------------------------------------------- /googlehome_scripts/Doorbell.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- show doorbell on devices that can show video 3 | # Author: Arul Selvan 4 | # Version: Nov 26, 2023 5 | # 6 | metadata: 7 | name: Doorbell 8 | description: Display doorbell on google displays, TVs etc. 9 | automations: 10 | - starters: 11 | - type: device.state.Online 12 | state: online 13 | is: true 14 | device: doorbell - Front door 15 | - type: assistant.event.OkGoogle 16 | eventData: query 17 | is: "show doorbell" 18 | condition: 19 | type: time.between 20 | after: 7:00 AM 21 | before: 10:00 PM 22 | actions: 23 | - type: assistant.command.OkGoogle 24 | devices: Homegen1 - Living Room 25 | okGoogle: "show my doorbell on Homegen1" 26 | - type: assistant.command.Broadcast 27 | message: Someone may be at the door, but I am not 100% sure. 28 | devices: 29 | - kitchen - Kitchen 30 | 31 | -------------------------------------------------------------------------------- /googlehome_scripts/FrenchPressTimer.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- Set a 4 min timer for frenchpress brew 3 | # Author: Arul Selvan 4 | # Version: Jun 24, 2023 5 | # 6 | metadata: 7 | name: French Press Timer 8 | description: Set a 4 min timer for frenchpress brew 9 | automations: 10 | - starters: 11 | - type: assistant.event.OkGoogle 12 | eventData: query 13 | is: "french press timer" 14 | actions: 15 | - type: assistant.command.OkGoogle 16 | devices: Homegen1 - Living Room 17 | okGoogle: "set a timer for 4 minutes on Homegen1" 18 | 19 | -------------------------------------------------------------------------------- /googlehome_scripts/Garage.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation 3 | # Close garrage if open >10 min, also broadcase a message. Turn lights on/off on cond. 4 | # Author: Arul Selvan 5 | # Version: Nov 26, 2023 6 | # 7 | metadata: 8 | name: Garage 9 | description: Close garage if open >10 min. Broadcase a message. Turn lights on/off cond. 10 | automations: 11 | # Starter: Garage door left open for more than 10 minutes. 12 | # Action to broadcase message to few google home speakers & close garrage. 13 | - starters: 14 | - type: device.state.OpenClose 15 | state: openPercent 16 | greaterThan: 0 17 | for: 10 min 18 | device: garage Door - Garage 19 | actions: 20 | - type: device.command.OpenClose 21 | openPercent: 0 22 | devices: garage Door - Garage 23 | - type: assistant.command.Broadcast 24 | message: The garage door was left open for more than 10 minutes, closing now. 25 | devices: 26 | - kitchen - Kitchen 27 | # Starter: Garage door is closing, broadcast a message to google home speakers 28 | - starters: 29 | - type: device.state.OpenClose 30 | device: garage Door - Garage 31 | state: openPercent 32 | is: 0 33 | actions: 34 | - type: assistant.command.Broadcast 35 | message: The garage door just closed. 36 | devices: 37 | - kitchen - Kitchen 38 | # Starter: When garage door closed, turn off kitchen if both conditions are met. 39 | - starters: 40 | - type: device.state.OpenClose 41 | state: openPercent 42 | is: 0 43 | device: garage Door - Garage 44 | # the & condition restricts closing between the time & home is away. 45 | # in other words, if anyone is home, just dont turn it off. 46 | condition: 47 | type: and 48 | conditions: 49 | - type: time.between 50 | after: 7:00 AM 51 | before: 5:00 PM 52 | - type: home.state.HomePresence 53 | state: homePresenceMode 54 | is: AWAY 55 | actions: 56 | - type: device.command.OnOff 57 | on: false 58 | devices: 59 | - kl1 - Kitchen 60 | # Starter: When garage door opens, turn on kitchen/living room if night time. 61 | - starters: 62 | - type: device.state.OpenClose 63 | state: openPercent 64 | greaterThan: 0 65 | device: garage Door - Garage 66 | condition: 67 | type: time.between 68 | after: 5:00 PM 69 | before: 1:00 AM 70 | actions: 71 | - type: device.command.OnOff 72 | on: true 73 | devices: 74 | - lr1 - Living Room 75 | - lr2 - Living Room 76 | - lr3 - Living Room 77 | - lr4 - Living Room 78 | - kl1 - Kitchen 79 | 80 | -------------------------------------------------------------------------------- /googlehome_scripts/Home-Away.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- turn on living room when entering home at dark or turn off when leaving at day time 3 | # Author: Arul Selvan 4 | # Version: Jul 19, 2023 5 | # 6 | metadata: 7 | name: Home-Away 8 | description: When entering home, turn on lights at night, turn off lights when leaving home at daytime 9 | automations: 10 | # Turn on living room when entering home after dark 11 | - starters: 12 | - type: home.state.HomePresence 13 | state: homePresenceMode 14 | is: HOME 15 | condition: 16 | type: time.between 17 | after: sunset 18 | before: sunrise 19 | actions: 20 | - type: device.command.OnOff 21 | devices: 22 | - lr1 - Living Room 23 | - lr2 - Living Room 24 | - lr3 - Living Room 25 | - lr4 - Living Room 26 | - kl1 - Kitchen 27 | on: true 28 | # Turn off living room lights when leaving home during day 29 | # Update: AWAY is randomly triggered so comment action for now and send a message instead 30 | - starters: 31 | - type: home.state.HomePresence 32 | state: homePresenceMode 33 | is: AWAY 34 | condition: 35 | type: time.between 36 | after: sunrise 37 | before: sunset 38 | actions: 39 | - type: assistant.command.Broadcast 40 | message: Away event noticed, is anyone home? 41 | devices: 42 | - Homegen1 - Living Room 43 | - kitchen - Kitchen 44 | #- type: device.command.OnOff 45 | # devices: 46 | # - lr1 - Living Room 47 | # - lr2 - Living Room 48 | # - lr3 - Living Room 49 | # - lr4 - Living Room 50 | # - kl1 - Kitchen 51 | # on: false 52 | 53 | -------------------------------------------------------------------------------- /googlehome_scripts/KitchenLight.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- turn on/off kitchen light 3 | # Author: Arul Selvan 4 | # Version: Oct 10, 2023 5 | # 6 | metadata: 7 | name: Kitchen Light 8 | description: Turn kitchen light on or off depending on command 9 | automations: 10 | - starters: 11 | - type: time.schedule 12 | at: 10:00 PM 13 | - type: time.schedule 14 | at: 2:30 PM 15 | - type: assistant.event.OkGoogle 16 | eventData: query 17 | is: "kitchen light off" 18 | actions: 19 | - type: device.command.OnOff # Turn the device on or off. 20 | on: false 21 | devices: 22 | - kl1 - Kitchen 23 | - starters: 24 | - type: time.schedule 25 | at: 7:30 AM 26 | - type: time.schedule 27 | at: 7:00 PM 28 | - type: assistant.event.OkGoogle 29 | eventData: query 30 | is: "kitchen light on" 31 | actions: 32 | - type: device.command.OnOff # Turn the device on or off. 33 | on: true 34 | devices: 35 | - kl1 - Kitchen 36 | 37 | -------------------------------------------------------------------------------- /googlehome_scripts/LivingroomLights.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- Livingroom lights on/off by voice & time of day 3 | # Author: Arul Selvan 4 | # Version: Nov 26, 2023 5 | # 6 | metadata: 7 | name: Livingroom Lights 8 | description: Livingroom lights on/off by voice & time of day 9 | automations: 10 | - starters: 11 | - type: time.schedule 12 | at: 7:30 AM 13 | - type: time.schedule 14 | at: 7:00 PM 15 | - type: time.schedule 16 | at: sunset-15min 17 | - type: assistant.event.OkGoogle 18 | eventData: query 19 | is: "living room on" 20 | actions: 21 | - type: device.command.OnOff # Turn the device on or off. 22 | on: true 23 | devices: 24 | - lr1 - Living Room 25 | - lr2 - Living Room 26 | - lr3 - Living Room 27 | - lr4 - Living Room 28 | - starters: 29 | - type: time.schedule 30 | at: 10:30 PM 31 | - type: time.schedule 32 | at: 2:30 PM 33 | - type: assistant.event.OkGoogle 34 | eventData: query 35 | is: "living room off" 36 | actions: 37 | - type: device.command.OnOff # Turn the device on or off. 38 | on: false 39 | devices: 40 | - lr1 - Living Room 41 | - lr2 - Living Room 42 | - lr3 - Living Room 43 | - lr4 - Living Room 44 | # Both Living room & Kitchen 45 | - starters: 46 | - type: assistant.event.OkGoogle 47 | eventData: query 48 | is: "living room and kitchen on" 49 | actions: 50 | - type: device.command.OnOff # Turn the device on or off. # Turn the device on or off. 51 | on: true 52 | devices: 53 | - kl1 - Kitchen 54 | - lr1 - Living Room 55 | - lr2 - Living Room 56 | - lr3 - Living Room 57 | - lr4 - Living Room 58 | - starters: 59 | - type: assistant.event.OkGoogle 60 | eventData: query 61 | is: "living room and kitchen off" 62 | actions: 63 | - type: device.command.OnOff # Turn the device on or off. # Turn the device on or off. 64 | on: false 65 | devices: 66 | - kl1 - Kitchen 67 | - lr1 - Living Room 68 | - lr2 - Living Room 69 | - lr3 - Living Room 70 | - lr4 - Living Room 71 | 72 | -------------------------------------------------------------------------------- /googlehome_scripts/PorchLights.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- Portch light on/off at sunset/sunrise also w/ voice 3 | # Author: Arul Selvan 4 | # Version: Jun 25, 2023 5 | # 6 | metadata: 7 | name: Porch Lights 8 | description: Portch light on/off at sunset/sunrise also w/ voice. 9 | automations: 10 | - starters: 11 | - type: time.schedule 12 | at: sunset+15min 13 | - type: assistant.event.OkGoogle 14 | eventData: query 15 | is: "porch on" 16 | actions: 17 | - type: device.command.OnOff # Turn the device on or off. 18 | on: true 19 | devices: 20 | - p1 - Porch 21 | - p2 - Porch 22 | - starters: 23 | - type: time.schedule 24 | at: sunrise-60min 25 | - type: assistant.event.OkGoogle 26 | eventData: query 27 | is: "porch off" 28 | actions: 29 | - type: device.command.OnOff # Turn the device on or off. 30 | on: false 31 | devices: 32 | - p1 - Porch 33 | - p2 - Porch 34 | 35 | -------------------------------------------------------------------------------- /googlehome_scripts/ReminderAnnouncements.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- reminder announcement 3 | # Author: Arul Selvan 4 | # Version: Aug 25, 2023 5 | # 6 | metadata: 7 | name: Reminder Announcements 8 | description: Various reminder announcements 9 | automations: 10 | - starters: 11 | - type: time.schedule 12 | at: 12:01 PM 13 | actions: 14 | - type: assistant.command.Broadcast 15 | devices: 16 | - kitchen - Kitchen 17 | #- ghmini - Bathroom 18 | #- homespeaker1 - Living Room 19 | #- Homegen2 - Bedroom 20 | message: This is a reminder to take blood pressure medication, now. 21 | 22 | -------------------------------------------------------------------------------- /googlehome_scripts/SleepTime.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- sleep time 3 | # Author: Arul Selvan 4 | # Version: Jun 15, 2023 5 | # 6 | metadata: 7 | name: Sleep Time 8 | description: Turn all the lights off at sleeptime, play rain sound for 15 min 9 | automations: 10 | - starters: 11 | #- type: time.schedule 12 | # at: 11:55 PM 13 | - type: assistant.event.OkGoogle 14 | eventData: query 15 | is: "sleep time" 16 | - type: assistant.event.OkGoogle 17 | eventData: query 18 | is: "bed time" 19 | - type: assistant.event.OkGoogle 20 | eventData: query 21 | is: "going to sleep" 22 | actions: 23 | - type: assistant.command.Broadcast 24 | message: "Alright, sleep time starts in 2 minutes ..." 25 | devices: Homegen2 - Bedroom 26 | - type: time.delay 27 | for: 2 min 28 | - type: device.command.OnOff 29 | devices: 30 | - b1 - Bedroom 31 | - b2 - Bedroom 32 | - b3 - Bedroom 33 | - b4 - Bedroom 34 | - bsl - Bedside 35 | - bsl2 - Bedside 36 | - lr1 - Living Room 37 | - lr2 - Living Room 38 | - lr3 - Living Room 39 | - lr4 - Living Room 40 | - u1 - Office 41 | - kl1 - Kitchen 42 | on: false 43 | # set the desired volume (not working) 44 | - type: device.command.SetVolume 45 | devices: Homegen2 - Bedroom 46 | volumeLevel: 10 47 | 48 | # turn off screen on device (may be not needed) 49 | - type: assistant.command.OkGoogle 50 | devices: Homegen2 - Bedroom 51 | okGoogle: "turn off screen" 52 | 53 | # play sound (flaky, does not play at all or plays sometime later) 54 | - type: assistant.command.OkGoogle 55 | devices: Homegen2 - Bedroom 56 | okGoogle: "play ocean sounds for 15 minutes" 57 | 58 | # seem like this is not working either 59 | - type: time.delay 60 | for: 16 minutes 61 | - type: assistant.command.OkGoogle 62 | devices: Homegen2 - Bedroom 63 | okGoogle: "stop" 64 | 65 | -------------------------------------------------------------------------------- /googlehome_scripts/TVLighting.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # selvans home automation --- TV lighting (lamp on/lights off) 3 | # Author: Arul Selvan 4 | # Version: Jun 16, 2023 5 | # 6 | metadata: 7 | name: TV lighting 8 | description: TV lighting (lamp on/lights off) 9 | automations: 10 | - starters: 11 | - type: time.schedule 12 | at: sunset-45min 13 | - type: assistant.event.OkGoogle 14 | eventData: query 15 | is: "tv lighting" 16 | actions: 17 | - type: device.command.OnOff # Turn the device on or off. 18 | on: true 19 | devices: 20 | - bsl - Bedside 21 | - bsl2 - Bedside 22 | - type: device.command.OnOff # Turn the device on or off. 23 | on: false 24 | devices: 25 | - b1 - Bedroom 26 | - b2 - Bedroom 27 | - b3 - Bedroom 28 | - b4 - Bedroom 29 | 30 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # install.sh --- Install script to setup this repo. 4 | # 5 | # PreReq: git must be installed 6 | # OS: Linux or MacOS 7 | # 8 | # Author: Arul Selvan 9 | # Version History: 10 | # Feb 2, 2024 --- Initial version 11 | # 12 | 13 | # ensure path for cron runs 14 | export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" 15 | 16 | # version format YY.MM.DD 17 | version=24.02.02 18 | my_name="`basename $0`" 19 | my_version="`basename $0` v$version" 20 | my_title="Script to download and setup to run scripts repo" 21 | my_logfile="/tmp/$(echo $my_name|cut -d. -f1).log" 22 | verbose=0 23 | 24 | # ensure path for cron runs 25 | export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" 26 | 27 | # commandline options 28 | options="p:vh?" 29 | 30 | # default install path 31 | script_home="${HOME}/src" 32 | scripts_dir="scripts.github" 33 | bashrc="${HOME}/.bashrc" 34 | 35 | # ripo home 36 | repo="https://github.com/aselvan/scripts.git" 37 | 38 | usage() { 39 | cat << EOF 40 | 41 | $my_name - $my_title 42 | 43 | Usage: $my_name [options] 44 | -p ---> Install path [Default: $script_home] 45 | -v ---> enable verbose, otherwise just errors are printed 46 | -h ---> print usage/help 47 | 48 | example: $my_name -p $script_home 49 | 50 | EOF 51 | exit 0 52 | } 53 | 54 | # parse commandline options 55 | while getopts $options opt; do 56 | case $opt in 57 | p) 58 | script_home="$OPTARG" 59 | ;; 60 | v) 61 | verbose=1 62 | ;; 63 | ?|h|*) 64 | usage 65 | ;; 66 | esac 67 | done 68 | 69 | echo "$my_version" | tee $my_logfile 70 | # check if git is available 71 | which git 2>&1 >/dev/null 72 | if [ $? -ne 0 ] ; then 73 | echo "[ERROR] missing git which is required. Install git and try again." | tee -a $my_logfile 74 | exit 1 75 | fi 76 | 77 | # check if path is already there and request to remove it first. 78 | if [ -d ${script_home}/${scripts_dir} ] ; then 79 | echo "[WARN] target path (${script_home}/${scripts_dir}) already exists, remove it and try again" | tee -a $my_logfile 80 | exit 2 81 | fi 82 | mkdir -p ${script_home}/${scripts_dir} 83 | 84 | cd ${script_home} || exit 3 85 | 86 | # clone the repo 87 | echo "[INFO] cloning repo $repo ..." 88 | git clone $repo $scripts_dir 2>&1 | tee -a $my_logfile 89 | 90 | # setup path in .bashrc 91 | echo "[INFO] adding PATH to $bashrc ..." 92 | SH="${script_home}/${scripts_dir}" 93 | path_to_append="export PATH=\"\$PATH:$SH/utils:$SH/security:$SH/tools:$SH/linux:$SH/macos:$SH/firewall\"" 94 | cp $bashrc ${bashrc}.backup 95 | echo "" >> $bashrc 96 | echo "# ------------- Added by $my_version ------------- " >> $bashrc 97 | echo $path_to_append >> $bashrc 98 | echo "export SCRIPTS_GITHUB=$SH" >> $bashrc 99 | echo "" >> $bashrc 100 | echo "[INFO] install done" 101 | exit 0 102 | -------------------------------------------------------------------------------- /iot/kasa/README.md: -------------------------------------------------------------------------------- 1 | # Kasa IoT bulb 2 | 3 | ### Simple shell script to turn on/off Kasa (TPlink) IoT devices using REST API 4 | 5 | - #### /kasa.sh 6 | Main script to turn on/off your Kasa bulb. This script is tested on macOS and Linux. 7 | 8 | # Disclaimer 9 | This kasa scripts uses TPlink/Kasa's unofficial/undocumented APIs and comes without warranty of any kind what so ever. You are free to use it at your own risk. I assume no liability for the accuracy, correctness, completeness, or usefulness of any information provided by this scripts nor for any sort of damages using these scripts may cause. 10 | 11 | # Credits 12 | https://docs.joshuatz.com/random/tp-link-kasa/
13 | https://github.com/michalmoczynski/homeassistant-tplink-integration 14 | 15 | # Setup 16 | Create a directory called 'kasa' in your $HOME directory and create a file named '.kasarc' in that directory and include your kasa cloud account username and password as shown below. 17 | 18 | mkdir $HOME/kasa
19 | echo -e "user=\"your kasa username\"\npassword=\"your kasa password\"" > $HOME/kasa/.kasarc 20 | 21 | # Usage 22 | 23 | ``` 24 | arul@lion$ ./kasa.sh -h 25 | 26 | Usage: kasa.sh [options] 27 | -a ---> one or more comma separated alias name of the device(s) to enable [ex: bulb1,bulb2] 28 | -e <1|0> ---> enable 1=on, 0=off 29 | -s ---> status 30 | -l ---> list all the Kasa IoT device alias names in your account 31 | -d ---> enable debugging output 32 | 33 | example: kasa.sh -a "bulb1, bulb2" -e 1 34 | ``` 35 | 36 | # Sample run 37 | ``` 38 | # The example below turns the bulb named 'l1' to ON 39 | 40 | arul@lion$ ./kasa.sh -a l1 -e 1 -d 41 | [INFO] seting device (l1) to state: 1 ... 42 | { 43 | "smartlife.iot.smartbulb.lightingservice": { 44 | "transition_light_state": { 45 | "on_off": 1, 46 | "mode": "normal", 47 | "hue": 0, 48 | "saturation": 0, 49 | "color_temp": 2700, 50 | "brightness": 100, 51 | "err_code": 0 52 | } 53 | } 54 | } 55 | [INFO] successfully set the state to 1 on device 'l1'! 56 | ``` 57 | 58 | ``` 59 | # The example below shows all Kasa IoT devices in the network/cloud account (note: DeviceId is masked ofcourse) 60 | 61 | arul@lion$ ./kasa.sh -l 62 | [INFO] retrieve device list ... 63 | [INFO] List of Kasa IoT devices found listed below: 64 | alias: p1; Model: KL110(US); Id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 65 | alias: l1; Model: LB100(US); Id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 66 | alias: bsl; Model: LB100(US); Id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 67 | alias: p2; Model: KL110(US); Id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 68 | alias: b2; Model: LB100(US); Id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 69 | alias: doorbell; Model: KD110(US); Id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 70 | ... 71 | ... 72 | 73 | ``` 74 | ``` 75 | # The example below gets the status of device 'l1' 76 | 77 | arul@lion$ ./kasa.sh -a l1 -s 78 | Device 'l1' status is written to the file '/Users/arul/kasa/l1.json' 79 | ``` 80 | -------------------------------------------------------------------------------- /java/java_installed_versions.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | # 3 | # java_installed_versions.sh --- simple script to check installed java is OpenJDK on Linux distros 4 | # 5 | # 6 | # Author: Arul Selvan 7 | # Version: May 24, 2021 8 | # 9 | 10 | my_name=`basename $0` 11 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 12 | # NOTE: This is not a fool proof way as someone could have installed java anywhere like /opt/myjava 13 | std_java_locations="/usr/lib/jvm/ /usr/java" 14 | 15 | check_java() { 16 | location=$1 17 | java_dirs=`find $location -maxdepth 1 -type d |awk 'NR >1 {print $1; }'` 18 | if [ -z "$java_dirs" ]; then 19 | echo "[INFO] no java found at '$location' " 20 | continue 21 | fi 22 | 23 | for jdir in $java_dirs ; do 24 | if [ -x $jdir/bin/java ] ; then 25 | java_vendor=`$jdir/bin/java -version 2>&1 | awk '/Runtime/ {print $1;}'` 26 | elif [ -x $jdir/jre/bin/java ] ; then 27 | java_vendor=`$jdir/jre/bin/java -version 2>&1 | awk '/Runtime/ {print $1;}'` 28 | else 29 | java_vendor="NOT Java Installation" 30 | fi 31 | echo -e "\t$jdir \t| $java_vendor" | tee -a $log_file 32 | done 33 | } 34 | 35 | echo "[INFO] checking java @`hostname` ..." 36 | for loc in $std_java_locations ; do 37 | if [ -d $loc ]; then 38 | check_java $loc 39 | fi 40 | done 41 | -------------------------------------------------------------------------------- /linux/check_bash_vulnerability.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # simple script to check if your bash is vulnerable. 4 | # 5 | # Author: Arul Selvan 6 | # Version: Sep 27, 2014 7 | 8 | env x='() { :;}; echo vulnerable' bash -c "echo end of test" 9 | -------------------------------------------------------------------------------- /linux/dmesg.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # Print human readable dmesg. 4 | # 5 | # Author: Arul Selvan 6 | # Version: Mar 17, 2012 7 | 8 | use strict; 9 | use warnings; 10 | 11 | my @dmesg_new = (); 12 | my $dmesg = "/bin/dmesg"; 13 | my @dmesg_old = `$dmesg`; 14 | my $now = time(); 15 | my $uptime = `cat /proc/uptime | cut -d"." -f1`; 16 | my $t_now = $now - $uptime; 17 | 18 | sub format_time { 19 | my @time = localtime $_[0]; 20 | $time[4]+=1; # Adjust Month 21 | $time[5]+=1900; # Adjust Year 22 | return sprintf '%4i-%02i-%02i %02i:%02i:%02i', @time[reverse 0..5]; 23 | } 24 | 25 | foreach my $line ( @dmesg_old ) 26 | { 27 | chomp( $line ); 28 | if( $line =~ m/\[\s*(\d+)\.(\d+)\](.*)/i ) 29 | { 30 | # now - uptime + sekunden 31 | my $t_time = format_time( $t_now + $1 ); 32 | push( @dmesg_new , "[$t_time] $3" ); 33 | } 34 | } 35 | 36 | print join( "\n", @dmesg_new ); 37 | print "\n"; 38 | -------------------------------------------------------------------------------- /linux/drop_cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # simple script to drop clean cache (memory and page) 4 | # 5 | # Author: Arul Selvan 6 | # Version: Jan 12, 2015 7 | 8 | user=`id -u` 9 | if [ $user -ne 0 ]; then 10 | echo "You need to be root to execute this script. Run w/ sudo" 11 | exit 12 | fi 13 | 14 | sync 15 | echo "Before drop_caches:" 16 | free -m 17 | echo "Dropping clean memory and page cache..." 18 | echo 3 >/proc/sys/vm/drop_caches 19 | sleep 2 20 | echo "After drop_caches:" 21 | free -m 22 | -------------------------------------------------------------------------------- /linux/find_zmeu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # find_zmeu.sh: 3 | # Desc: finds the unique IPs, hosts trying to do look for php vulnerabilities in our apache server 4 | # Author : Arul 5 | # Version : May 7, 2011 6 | # 7 | # Source info: http://ensourced.wordpress.com/2011/02/25/zmeu-attacks-some-basic-forensic/ 8 | # 9 | 10 | httpLogFile=/var/log/apache2/access.log 11 | zmeuLogFile=/var/www/zmeuAttackers.html 12 | std_header=/var/www/std_header.html 13 | #ufwRules=/var/lib/ufw/user.rules 14 | ufwRules=/lib/ufw/user.rules 15 | 16 | title="selvans.net zmenu log" 17 | desc="This file contains selvans.net zmenu log" 18 | sed_st="s/__TITLE__/$title/g;s/__DESC__/$desc/g" 19 | 20 | cat $std_header |sed -e "$sed_st" > $zmeuLogFile 21 | echo "

IPs/Hosts that does ZmEu attacks/scan


" >> $zmeuLogFile
22 | echo "Run date: `date +"%D"`" >> $zmeuLogFile
23 | echo "Source info: http://ensourced.wordpress.com/2011/02/25/zmeu-attacks-some-basic-forensic/" >> $zmeuLogFile
24 | echo "" >> $zmeuLogFile
25 | echo "IP/Hosts List below (need to add to iptables periodically)" >> $zmeuLogFile
26 | echo "" >> $zmeuLogFile
27 | echo "" >> $zmeuLogFile
28 | echo "" >> $zmeuLogFile
29 | #cat $httpLogFile |grep ZmEu |awk '{print $1;}'|sort|uniq >> $zmeuLogFile
30 | output=$(cat $httpLogFile |grep ZmEu |awk '{print $1;}'|sort|uniq)
31 | for hostName in $output;  do
32 |     # see if the lookup succeeds
33 |     lookup=`host $hostName 2>/dev/null`
34 |     if [ $? -eq 0 ]; then
35 |         hostIp=`echo $lookup|awk '{print $3}'`
36 |         # see it is already blocked
37 | 	grep $hostIp $ufwRules >/dev/null 2>&1
38 |         if [ $? -eq 0 ]; then
39 |            blocked=Yes
40 | 	else
41 |            blocked=No
42 |         fi
43 |         whoisInfo=`whois $hostIp| egrep -w 'descr:|owner:|e-mail:'`
44 |     else
45 |         hostIp="N/A"
46 |         # see it is already blocked
47 | 	grep $hostName $ufwRules >/dev/null 2>&1
48 |         if [ $? -eq 0 ]; then
49 |            blocked=Yes
50 | 	else
51 |            blocked=No
52 |         fi
53 |         whoisInfo=`whois $hostName| egrep -w 'descr:|owner:|e-mail:'`
54 |     fi
55 |     echo "" >> $zmeuLogFile
56 | done
57 | echo "
HostIPIn iptables?Whois Info
$hostName$hostIp$blocked$whoisInfo
" >> $zmeuLogFile 58 | -------------------------------------------------------------------------------- /linux/flush_iptables.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sudo iptables -t nat -F; sudo iptables -t mangle -F; sudo iptables -F; sudo iptables -X 3 | -------------------------------------------------------------------------------- /linux/iptables_block_ms.sh: -------------------------------------------------------------------------------- 1 | # 2 | # iptables_rules.sh 3 | # 4 | # simple iptables rule to block microsoft CIDR 134.170.0.0/16 5 | # 6 | # Author: Arul Selvan 7 | # Version: jun 7, 2014 8 | # 9 | iptables -F 10 | iptables -A INPUT -s 134.170.0.0/16 -j DROP 11 | iptables -A OUTPUT -d 134.170.0.0/16 -j DROP 12 | 13 | iptables -L -n -v 14 | -------------------------------------------------------------------------------- /linux/iptables_lb_fake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # IP tables rules to fake failure on every 3rd req. 4 | # 5 | # Basically, forward 80 to an external host based on the state "NEW" connection 6 | # and forward the 3rd "NEW" connection to local host (assuming there is no 80 7 | # service) therefore it will fail. Also, log it. 8 | # 9 | # Author: Arul Selvan 10 | # Version: Jun 2017 11 | # 12 | #sysctl net.ipv4.ip_forward=1 13 | 14 | # change as needed 15 | PORT=80 16 | REAL_DEST=192.168.1.11 17 | INTERFACE=wlan0 18 | 19 | echo "1" > /proc/sys/net/ipv4/ip_forward 20 | iptables -F 21 | iptables -t nat -F 22 | iptables -t nat -A POSTROUTING -p tcp --dport $PORT -j MASQUERADE 23 | iptables -t nat -A PREROUTING -p tcp -i $INTERFACE --dport $PORT -m state --state NEW -m statistic --mode nth --every 3 --packet 0 -j DNAT --to-destination $REAL_DEST:$PORT 24 | iptables -t nat -A PREROUTING -p tcp -i $INTERFACE --dport $PORT -m state --state NEW -m statistic --mode nth --every 3 --packet 1 -j DNAT --to-destination $REAL_DEST:$PORT 25 | iptables -t nat -A PREROUTING -p tcp -i $INTERFACE --dport $PORT -m state --state NEW -m statistic --mode nth --every 3 --packet 2 -j REDIRECT --to-ports $PORT 26 | iptables -A INPUT -p tcp -i $INTERFACE --dport $PORT -m state --state NEW -j LOG --log-prefix "[DROP'ing $PORT]: " --log-level 2 27 | iptables -A INPUT -p tcp -i $INTERFACE --dport $PORT -m state --state NEW -j REJECT 28 | 29 | -------------------------------------------------------------------------------- /linux/max_capacity_change.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # max_capacity_change.sh -- crude shell script to change the max capacity of db2 datasource entries 4 | # 5 | # Author: Arul Selvan 6 | # Version: Apr 18, 2014 7 | 8 | # the max capacity to change to 9 | max_capacity=1 10 | backup_ext="odsfix" 11 | # find only the db2 datasource (can be *.xml also). 12 | db2_data_sources=`find . -name \*.xml -exec grep -l "localhost:50000" {} \;` 13 | 14 | function change { 15 | for name in $db2_data_sources ; do 16 | cp $name ${name}.${backup_ext} || exit 17 | sed -i "s|\(\)[^<>]*\(\)|\1${max_capacity}\2|g" $name 18 | sed -i "s|\(\)[^<>]*\(\)|\1${max_capacity}\2|g" $name 19 | sed -i "s|\(\)[^<>]*\(\)|\1${max_capacity}\2|g" $name 20 | done 21 | } 22 | 23 | function restore { 24 | for name in $db2_data_sources ; do 25 | # to be safe do a move/overwrite *only* if we find a backup file 26 | if [ -e ${name}.${backup_ext} ]; then 27 | mv ${name}.${backup_ext} $name 28 | fi 29 | done 30 | } 31 | 32 | if [ $# -ne 1 ]; then 33 | echo "Usage: `basename $0` " 34 | exit 35 | fi 36 | 37 | if [ "$1" = "change" ]; then 38 | change 39 | elif [ "$1" = "restore" ]; then 40 | restore 41 | fi 42 | -------------------------------------------------------------------------------- /linux/oom_score.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # oom_score.sh --- prints the oom score,adjustment score of running processes 3 | # 4 | # Author: Arul Selvan 5 | # Version: Jan 26, 2020 6 | # 7 | 8 | printf 'PID\tOOM Score\tOOM Adj\tCommand\n' 9 | 10 | while read -r pid comm; do 11 | [ -f /proc/$pid/oom_score ] && 12 | #[ $(cat /proc/$pid/oom_score) != 0 ] && 13 | printf '%d\t%d\t\t%d\t%s\n' "$pid" "$(cat /proc/$pid/oom_score)" "$(cat /proc/$pid/oom_score_adj)" "$comm"; 14 | done < <(ps -e -o pid= -o comm=) | sort -k2nr 15 | -------------------------------------------------------------------------------- /linux/process_info.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | # 4 | # process_info.sh --- find process details given port the process listens to 5 | # 6 | # Author: Arul Selvan 7 | # Version: Jan 11, 2020 8 | # 9 | 10 | # ensure this script runs under cron w/ out having to set full path 11 | export PATH="/sbin:/bin:/usr/sbin:/usr/bin:${PATH}" 12 | 13 | # default port for obc 8045 (or) 9403 14 | port=8045 15 | log_file="" 16 | pid="" 17 | pname="" 18 | rss_mb="" 19 | options_list="p:f:h?" 20 | 21 | check_root() { 22 | if [ `id -u` -ne 0 ] ; then 23 | echo "[ERROR] you must be 'root' to run this script... exiting." 24 | exit 25 | fi 26 | } 27 | 28 | usage() { 29 | echo "Usage: $0 [-p ]" 30 | echo " listeningPort -- port the process listens to locate the process" 31 | exit 32 | } 33 | 34 | collect_info() { 35 | # get pid and name 36 | pid=`lsof -ti :$port -s TCP:LISTEN` 37 | if [ -z $pid ] ; then 38 | echo "[ERROR] no process is listening on $port" 39 | exit 40 | fi 41 | pname=`lsof -i :$port -s TCP:LISTEN|awk '{if(NR==2)print $1}'` 42 | 43 | # find number of open fd's which includes sockets 44 | fd_count=`ls -l /proc/$pid/fd|wc -l` 45 | if [ -z $fd_count ] ; then 46 | echo "[ERROR] something wrong, the process $pid apparently had no open fd" 47 | exit 48 | fi 49 | 50 | # get process rss size 51 | rss=`ps --no-header -vp $pid | grep -v grep | awk '{print $8;}'` 52 | if [ -z $rss ] ; then 53 | echo "[ERROR] something wrong, cant find RSS!" 54 | exit 55 | fi 56 | rss_mb=$(echo "scale=2; $rss/1024"|bc -l) 57 | } 58 | 59 | while getopts "$options_list" opt; do 60 | case $opt in 61 | p) 62 | port=$OPTARG 63 | ;; 64 | f) 65 | log_file=$OPTARG 66 | ;; 67 | h) 68 | usage 69 | ;; 70 | \?) 71 | usage 72 | ;; 73 | :) 74 | usage 75 | ;; 76 | esac 77 | done 78 | 79 | check_root 80 | timestamp=`date +'%D %T'` 81 | collect_info 82 | 83 | if [ -z $log_file ] ; then 84 | echo "Timestamp Open FDs RSS (MB) Name PID" 85 | echo "$timestamp $fd_count $rss_mb $pname $pid" 86 | else 87 | if [ ! -f $log_file ] ; then 88 | echo "Timestamp, Open FDs, RSS (MB), Name, PID" > $log_file 89 | fi 90 | echo "$timestamp, $fd_count, $rss_mb, $pname, $pid" >> $log_file 91 | fi 92 | 93 | exit 0 94 | -------------------------------------------------------------------------------- /linux/rss_size.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # simple script to count RSS size of specificed process or all processes 4 | # 5 | # Author: Arul Selvan 6 | # Version: Nov 12, 2012 7 | 8 | filter=$1 9 | 10 | if [ ! -z "$filter" ]; then 11 | echo "Counting RSS size of process: $filter" 12 | rss_kbytes=`ps -augx --no-header | grep $filter | grep -v grep | awk '{print $6;}' |paste -sd+|bc` 13 | else 14 | echo "Counting RSS size of all processes" 15 | rss_kbytes=`ps -augx --no-header | grep -v grep | awk '{print $6;}' |paste -sd+|bc` 16 | fi 17 | 18 | echo "Size: $rss_kbytes KB or $(echo "scale=2; $rss_kbytes/1024" | bc -l) MB or $(echo "scale=2; $rss_kbytes/(1024*1024)" | bc -l) GB" 19 | -------------------------------------------------------------------------------- /linux/service_connection_count.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | # 4 | # service_connection_count.sh --- count remote tcp conncections to specific service port 5 | # 6 | # Author: Arul Selvan 7 | # Version: Jan 11, 2020 8 | # 9 | 10 | # ensure this script runs under cron w/ out having to set full path 11 | export PATH="/sbin:/bin:/usr/sbin:/usr/bin:${PATH}" 12 | 13 | # default port oracle (1521) 14 | port=1521 15 | log_file="" 16 | starting="" 17 | starting_state="SYN_SENT" 18 | established="" 19 | established_state="ESTABLISHED" 20 | closing="" 21 | closing_state="CLOSING,CLOSE_WAIT,FIN_WAIT1,FIN_WAIT2,CLOSED,TIME_WAIT,LAST_ACK" 22 | 23 | os_name=`uname -s` 24 | options_list="p:f:h?" 25 | 26 | check_root() { 27 | if [ `id -u` -ne 0 ] ; then 28 | echo "[ERROR] you must be 'root' to run this script... exiting." 29 | exit 30 | fi 31 | } 32 | 33 | usage() { 34 | echo "Usage: $0 [-p ]" 35 | echo " servicePort --- remote service port to get total number of connections" 36 | exit 37 | } 38 | 39 | collect_info() { 40 | # active connections 41 | starting=`lsof -ti :$port -s TCP:$starting_state |wc -l` 42 | established=`lsof -ti :$port -s TCP:$established_state |wc -l` 43 | closing=`lsof -ti :$port -s TCP:$closing_state|wc -l` 44 | 45 | # this not exactly accurate since it is possible for multiple process to connect to same 46 | # service but it is not very likely so we assume that is not the case. 47 | pname=`lsof -i :$port -s TCP:$starting_state,$established_state,$closing_state |awk '{if (NR==2) print $1}'` 48 | if [ -z $pname ] ; then 49 | pname="N/A" 50 | fi 51 | } 52 | 53 | check_root 54 | if [ $os_name = "Darwin" ]; then 55 | closing_state="CLOSING,CLOSE_WAIT,FIN_WAIT_1,FIN_WAIT_2,CLOSED,LAST_ACK" 56 | fi 57 | 58 | while getopts "$options_list" opt; do 59 | case $opt in 60 | p) 61 | port=$OPTARG 62 | ;; 63 | f) 64 | log_file=$OPTARG 65 | ;; 66 | h) 67 | usage 68 | ;; 69 | \?) 70 | usage 71 | ;; 72 | :) 73 | usage 74 | ;; 75 | esac 76 | done 77 | 78 | timestamp=`date +'%D %T'` 79 | collect_info 80 | 81 | if [ -z $log_file ] ; then 82 | printf "Timestamp\t\t TCP:starting\t TCP:established\t TCP:closing\t Name\t ServicePort\n" 83 | printf "$timestamp\t $starting\t\t $established\t\t\t $closing\t\t $pname\t $port\n" 84 | else 85 | if [ ! -f $log_file ] ; then 86 | echo "Timestamp, TCP:starting, TCP:established, TCP:closing, Name, ServicePort" > $log_file 87 | fi 88 | echo "$timestamp, $starting, $established, $closing, $pname, $port" >> $log_file 89 | fi 90 | 91 | exit 0 92 | -------------------------------------------------------------------------------- /linux/vfs_cache_pressure.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # vfs_cache_pressure.sh --- check performace diff between 100 vs 50 for vfs_cache_pressure 3 | # 4 | # Author: Arul Selvan 5 | # Version: Jan 26, 2020 6 | # 7 | 8 | echo "Test cache pressure 100 vs 50" 9 | sync 10 | echo 3 > /proc/sys/vm/drop_caches 11 | dd if=/dev/zero of=/tmp/testfile count=1 bs=900M >/dev/null 2>&1 12 | 13 | sysctl -w vm.vfs_cache_pressure=100 >/dev/null 2>&1 14 | find / > /dev/null 15 | cp /tmp/testfile /tmp/testfile2 >/dev/null 2>&1 16 | echo "---------- Pressure = 100 ----------------" 17 | time find / > /dev/null 18 | 19 | sysctl -w vm.vfs_cache_pressure=50 >/dev/null 2>&1 20 | find / > /dev/null 21 | echo "----------- Pressure = 50 ----------------" 22 | cp /tmp/testfile2 /tmp/testfile3 >/dev/null 2>&1 23 | time find / > /dev/null 24 | 25 | rm -f /tmp/testfile /tmp/testfile2 /tmp/testfile3 26 | -------------------------------------------------------------------------------- /macos/README.md: -------------------------------------------------------------------------------- 1 | # macOS 2 | 3 | ### A collection of totally random scripts for macOS 4 | 5 | - #### /free_wifi.sh 6 | Shell script to get free wifi by spoofing an authenticated mac address on a paid wifi service like inflight wifi. 7 | 8 | - #### /crashplan.sh 9 | Enable and disable crashplan service/agents. 10 | -------------------------------------------------------------------------------- /macos/auto_sshfs: -------------------------------------------------------------------------------- 1 | # 2 | # auto_sshfs: MacOS automount map for sshfs 3 | # 4 | # auto_sshfs --- MacOS auto mount definition for automounter for sshfs. 5 | # 6 | # Pre req: 7 | # - You must have the following packages installed for this script to work 8 | # - setup ssh keybased login to avoid entering password on mount 9 | # 10 | # brew install sshfs 11 | # 12 | # Setup/Install: 13 | # 14 | # Copy this file to /etc & edit /etc/auto_master and add an entry as shown below 15 | # 16 | # /Users/arul/mnt/sshfs /etc/auto_sshfs 17 | # 18 | # The first entry above is a mount point where sshfs will be mounted under 19 | # using the specified 'mountname' below. The second entry is path or link 20 | # to this file. This also needs mount_sshfs.sh script which is found in the 21 | # same directory as this file and should be symlinked (or copied) to /sbin 22 | # as shown below for ssh automount to work. 23 | # 24 | # ln -s mount_sshfs.sh /sbin/mount_sshfs 25 | # 26 | # Note: Apple makes it harder now (i.e. since Catalina update) by making /sbin 27 | # readonly so you have to turn off SIP in order to place this as a soft link 28 | # (or copy) under /sbin. 29 | # 30 | # Once linked (or copied), restart the automountd like shown below 31 | # 32 | # sudo automount -vc 33 | # 34 | # Finally, when the user cd to the 'mountname', automountd will call 35 | # /sbin/mount_ i.e. mount_sshfs and pass on the 'hostpath' argument. 36 | # 37 | # Author: Arul Selvan 38 | # Version: Aug 29, 2014 39 | # Version: Apr 12. 2020 (updated for catalina as MacOS changed automounter behaviour) 40 | # 41 | # -------------------- mount entry start ------------------------ 42 | # mount entry format: 43 | # 44 | # mountname mountoptions hostpath (i.e. ssh commandline ex: user@host:/path/path) 45 | # 46 | # CAUTION: Change the directory name, user, path etc before using this file. 47 | work-data -fstype=sshfs,nodev,nobrowse,nosuid,allow_other,uid=501,gid=20 aselvan@aselvanrp:/Users/aselvan/data 48 | -------------------------------------------------------------------------------- /macos/crashplan.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | # 4 | # crashplan.sh --- enable/disable crashplan (code42) agent and daemon on MacOS 5 | # 6 | # Allows to manually start and stop the service on a 'as needed' basis since 7 | # this service spins and chews up resources all day long even when set to 8 | # backup during midnight! 9 | # 10 | # Usage: Setup two cronjobs (one to enable, one to disable) night time to allow 11 | # backup to occur. Also, setup the backup schedule on the code42 UI for serveral 12 | # hours between start/stop of cron to have backup occur. 13 | # 14 | # Author: Arul Selvan 15 | # Version: Dec 21, 2018 16 | # 17 | 18 | # make sure to change this to your username crashplan is licensed to 19 | user_name="aselvan" 20 | # should provide effective username on normal and elevated runs 21 | #user_name=`who -m | awk '{print $1;}'` 22 | log_file="/tmp/crashplan.log" 23 | 24 | # plists 25 | crashplan_daemons_plist="/Library/LaunchDaemons/com.crashplan.engine.plist /Library/LaunchDaemons/com.code42.service.plist" 26 | crashplan_agent_plist="/Users/${user_name}/Library/LaunchAgents/com.code42.menubar.plist" 27 | 28 | # crashplan ui 29 | #cp_ui="/Applications/CrashPlan.app/Contents/MacOS/CrashPlanWeb" 30 | cp_ui="/Applications/Code42.app/Contents/MacOS/Code42Desktop" 31 | 32 | check_root() { 33 | if [ `id -u` -ne 0 ] ; then 34 | echo "[ERROR] you must be 'root' to run this script... exiting." | tee -a $log_file 35 | exit 36 | fi 37 | } 38 | 39 | enable() { 40 | echo "[INFO] enabling daemons ..." | tee -a $log_file 41 | for p in $crashplan_daemons_plist ; do 42 | if [ -f $p ] ; then 43 | echo "\tEnabling: $p" | tee -a $log_file 44 | launchctl load -w $p >>$log_file 2>&1 45 | fi 46 | done 47 | 48 | echo "[INFO] enabling launch agents ..." | tee -a $log_file 49 | for a in $crashplan_agent_plist ; do 50 | if [ -f $a.disabled ] ; then 51 | echo "\tEnabling: $a" | tee -a $log_file 52 | mv $a.disabled $a >> $log_file 2>&1 53 | fi 54 | done 55 | 56 | echo "[INFO] starting the UI ..." |tee -a $log_file 57 | # start the UI 58 | cd /Users/$user_name || exit 59 | sudo -u $user_name $cp_ui >>$log_file 2>&1 & 60 | } 61 | 62 | disable() { 63 | echo "[INFO] disabling launch daemons ..." | tee -a $log_file 64 | for p in $crashplan_daemons_plist ; do 65 | if [ -f $p ] ; then 66 | echo "\tDisabling: $p" | tee -a $log_file 67 | launchctl unload -w $p >>$log_file 2>&1 68 | fi 69 | done 70 | 71 | echo "[INFO] disabling launch agents ..." | tee -a $log_file 72 | for a in $crashplan_agent_plist ; do 73 | if [ -f $a ] ; then 74 | echo "\tDisabling: $a" | tee -a $logfile 75 | mv $a $a.disabled >> $log_file 2>&1 76 | fi 77 | done 78 | } 79 | 80 | echo "$0 starting..." > $log_file 81 | check_root 82 | 83 | case $1 in 84 | enable|disable) "$@" 85 | ;; 86 | *) echo "Usage: $0 " 87 | ;; 88 | esac 89 | 90 | exit 0 91 | -------------------------------------------------------------------------------- /macos/cylance.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | # 4 | # cylance.sh --- enable/disable cylance 5 | # 6 | # Author: Arul Selvan 7 | # Version: Jan 2, 2019 8 | # 9 | 10 | # works with user login or elevated 11 | user=`who -m | awk '{print $1;}'` 12 | 13 | # list of jamf plists 14 | launch_daemons_plist="\ 15 | /Library/LaunchDaemons/com.cylance.agent_service.plist \ 16 | " 17 | launch_agents_plist="\ 18 | /Library/LaunchAgents/com.cylancePROTECT.plist \ 19 | " 20 | 21 | check_root() { 22 | if [ `id -u` -ne 0 ] ; then 23 | echo "[ERROR] you must be 'root' to run this script... exiting." 24 | exit 25 | fi 26 | } 27 | 28 | enable() { 29 | echo "[INFO] enabling launch daemons for all users ..." 30 | for p in $launch_daemons_plist ; do 31 | if [ -f $p ] ; then 32 | echo "Enabling: $p" 33 | sudo launchctl load $p 34 | fi 35 | done 36 | 37 | echo "[INFO] enabling launch agents for this user ..." 38 | for p in $launch_agents_plist ; do 39 | if [ -f $p ] ; then 40 | echo "Enabling: $p" 41 | launchctl load $p 42 | fi 43 | done 44 | } 45 | 46 | disable() { 47 | echo "[INFO] disabling launch daemons for all users ..." 48 | for p in $launch_daemons_plist ; do 49 | if [ -f $p ] ; then 50 | echo "Disable: $p" 51 | sudo launchctl unload -w $p 52 | fi 53 | done 54 | 55 | echo "[INFO] disabling launch agents for this user ..." 56 | for p in $launch_agents_plist ; do 57 | if [ -f $p ] ; then 58 | echo "Disable: $p" 59 | launchctl unload -w $p 60 | fi 61 | done 62 | } 63 | 64 | #check_root 65 | 66 | case $1 in 67 | enable|disable) "$@" 68 | ;; 69 | *) echo "Usage: $0 " 70 | ;; 71 | esac 72 | 73 | exit 0 74 | -------------------------------------------------------------------------------- /macos/freestyle_libre.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | # 4 | # freestyle_libre.sh --- enable/disable freeStyle Libre glucometer support service on MacOS 5 | # 6 | # Allows to manually start and stop the service on a 'as needed' basis since 7 | # this service spins and chews up resources all day long for no reason 8 | # 9 | # Cant remove Libre FreeStyle blood glucometer helper/opener app because 10 | # it also does other crap needed for ther reader app, so disable it 11 | # so we can enable when using the app. 12 | # 13 | # Author: Arul Selvan 14 | # Version: Sep 8, 2019 15 | # 16 | 17 | 18 | log_file="/tmp/freestyle_libre.log" 19 | 20 | # plists 21 | libre_daemons_plist="/Library/LaunchDaemons/com.abbott.FreeStyleLibreMAS.plist" 22 | 23 | check_root() { 24 | if [ `id -u` -ne 0 ] ; then 25 | echo "[ERROR] you must be 'root' to run this script... exiting." | tee -a $log_file 26 | exit 27 | fi 28 | } 29 | 30 | enable() { 31 | echo "[INFO] enabling libre helper ..." | tee -a $log_file 32 | for p in $libre_daemons_plist ; do 33 | if [ -f $p ] ; then 34 | echo "\tEnabling: $p" | tee -a $log_file 35 | launchctl load -w $p >>$log_file 2>&1 36 | else 37 | echo "\tDamon plist: $p not found" 38 | fi 39 | done 40 | } 41 | 42 | disable() { 43 | echo "[INFO] disabling libre helper ..." | tee -a $log_file 44 | for p in $libre_daemons_plist ; do 45 | if [ -f $p ] ; then 46 | echo "\tDisabling: $p" | tee -a $log_file 47 | launchctl unload -w $p >>$log_file 2>&1 48 | else 49 | echo "\tDamon plist: $p not found" 50 | fi 51 | done 52 | } 53 | 54 | echo "$0 starting..." > $log_file 55 | check_root 56 | 57 | case $1 in 58 | enable|disable) "$@" 59 | ;; 60 | *) echo "Usage: $0 " 61 | ;; 62 | esac 63 | 64 | exit 0 65 | -------------------------------------------------------------------------------- /macos/mount_sshfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # mount_sshfs.sh --- wrapper script for automountd to invoke 5 | # 6 | # This should be soft linked (or copied) to /sbin for automountd. Apple makes 7 | # it harder now (i.e. since Catalina update) by making /sbin readonly so you 8 | # have to turn off SIP in order to place this as a soft link under /sbin for 9 | # ssh automount path defined in /etc/auto_sshfs to work. 10 | # 11 | # ln -s mount_sshfs.sh /sbin/mount_sshfs 12 | # 13 | # Author: Arul Selvan 14 | # Version: Apr 12, 2020 15 | # 16 | log_file=/tmp/mount_ssh.log 17 | 18 | echo "[INFO] `date`: mount_sshfs.sh starting " > $log_file 19 | echo "[INFO] Mount command: $@ ..." >> $log_file 20 | sudo /usr/local/bin/sshfs $@ 21 | -------------------------------------------------------------------------------- /macos/msteam.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # msteam.sh --- wrapper to avoid ms-team behave like a pig draining power and cpu 5 | # 6 | # In addition to disabling gpu usage, restrict msteam to not to compete with other 7 | # apps for cpu by lowering priority to the absolute minimum. In addition, if available, 8 | # and option is specified, this script will use 'cpulimit' tool to lock it down CPU usage 9 | # 10 | # Optional: You can install the 'cpulimit' with Homebrew i.e. brew install cpulimit 11 | # 12 | # Note: Most modern macs have 4 cores so the 100% (default value) will be limiting 13 | # your msteam to use only 1 full CPU core, however msteam fork/exec's 4 child 14 | # process so in theory each process can get upto 100% CPU! so you can't win 15 | # w/ this cpu pig! So the bottomline, it can potentially go up to 400% at the 16 | # worst case but it doesnt seem to be going more than 100% which is good. 17 | # 18 | # Author: Arul Selvan 19 | # Version: Jan 23, 2020 20 | # 21 | 22 | log_file=/tmp/msteam.log 23 | cpu_percent="" 24 | cpu_limit_bin=/usr/local/bin/cpulimit 25 | options_list="l:h" 26 | script_name=`basename $0` 27 | 28 | 29 | usage() { 30 | echo "Usage: $script_name [-l ]" 31 | exit 1 32 | } 33 | 34 | # parse args 35 | while getopts "$options_list" opt; do 36 | case $opt in 37 | l) 38 | cpu_percent=$OPTARG 39 | ;; 40 | h) 41 | usage 42 | ;; 43 | *) 44 | usage 45 | ;; 46 | esac 47 | done 48 | 49 | echo "[INFO] Starting MS-Team with gpu disabled." 50 | 51 | # if cpulimit requested and tool is available, use it 52 | if [[ ! -z $cpu_percent && -x $cpu_limit_bin ]] ; then 53 | echo "[INFO] using cpulimit tool to limit $cpu_percent% of CPU usage" 54 | $cpu_limit_bin -l $cpu_percent -i nice -n 20 nohup /Applications/Microsoft\ Teams.app/Contents/MacOS/Teams --disable-gpu > $log_file 2>&1 & 55 | else 56 | nice -n 20 nohup /Applications/Microsoft\ Teams.app/Contents/MacOS/Teams --disable-gpu > $log_file 2>&1 & 57 | fi 58 | -------------------------------------------------------------------------------- /macos/net.selvans.network_change.plist: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Label 7 | net.selvans.network_change 8 | LowPriorityIO 9 | 10 | ProgramArguments 11 | 12 | /Library/LaunchDaemons/net.selvans.network_change.sh 13 | 14 | WatchPaths 15 | 16 | /private/var/run/resolv.conf 17 | 18 | RunAtLoad 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /macos/pa_trap_agent.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | # 4 | # cylance.sh --- enable/disable paloalto trap agent on demand 5 | # 6 | # Author: Arul Selvan 7 | # Version: Jan 4, 2020 8 | # 9 | 10 | # works with user login or elevated 11 | user=`who -m | awk '{print $1;}'` 12 | 13 | # list of daemons plists 14 | launch_daemons_plist="\ 15 | /Library/LaunchDaemons/com.paloaltonetworks.trapsd.plist \ 16 | /Library/LaunchDaemons/com.paloaltonetworks.pmd.plist \ 17 | /Library/LaunchDaemons/com.paloaltonetworks.authorized.plist \ 18 | " 19 | launch_agents_plist="\ 20 | /Library/LaunchAgents/com.paloaltonetworks.traps_agent.plist \ 21 | " 22 | 23 | check_root() { 24 | if [ `id -u` -ne 0 ] ; then 25 | echo "[ERROR] you must be 'root' to run this script... exiting." 26 | exit 27 | fi 28 | } 29 | 30 | enable() { 31 | echo "[INFO] enabling launch daemons for all users ..." 32 | for p in $launch_daemons_plist ; do 33 | if [ -f $p ] ; then 34 | echo "Enabling: $p" 35 | sudo launchctl load $p 36 | fi 37 | done 38 | 39 | echo "[INFO] enabling launch agents for this user ..." 40 | for p in $launch_agents_plist ; do 41 | if [ -f $p ] ; then 42 | echo "Enabling: $p" 43 | launchctl load $p 44 | fi 45 | done 46 | } 47 | 48 | disable() { 49 | echo "[INFO] disabling launch daemons for all users ..." 50 | for p in $launch_daemons_plist ; do 51 | if [ -f $p ] ; then 52 | echo "Disable: $p" 53 | sudo launchctl unload -w $p 54 | fi 55 | done 56 | 57 | echo "[INFO] disabling launch agents for this user ..." 58 | for p in $launch_agents_plist ; do 59 | if [ -f $p ] ; then 60 | echo "Disable: $p" 61 | launchctl unload -w $p 62 | fi 63 | done 64 | } 65 | 66 | #check_root 67 | 68 | case $1 in 69 | enable|disable) "$@" 70 | ;; 71 | *) echo "Usage: $0 " 72 | ;; 73 | esac 74 | 75 | exit 0 76 | -------------------------------------------------------------------------------- /macos/remove_launchd_items.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # remove_launchd_items.sh - removes unwanted autolaunch entries from MacOS 4 | # stock image. Must run with sudo 5 | # 6 | # Author: Arul Selvan 7 | # Version: Sep 1, 2014 8 | # 9 | extended="$1" 10 | 11 | uid=`id -u` 12 | if [ $uid -ne 0 ]; then 13 | echo "You need to run this script as sudo" 14 | exit 15 | fi 16 | 17 | # items to remove safely 18 | items_to_remove="\ 19 | /System/Library/LaunchDaemons/org.apache.httpd.plist \ 20 | /System/Library/LaunchDaemons/org.ntp.ntpd.plist \ 21 | /Library/LaunchDaemons/com.adobe.fpsaud.plist \ 22 | /Library/LaunchDaemons/com.google.keystone.daemon.plist \ 23 | /Library/LaunchDaemons/com.omnigroup.OmniSoftwareUpdate.OSUInstallerPrivilegedHelper.plist \ 24 | /Library/LaunchDaemons/com.oracle.java.Helper-Tool.plist \ 25 | /Library/LaunchAgents/com.adobe.AAM.Updater-1.0.plist \ 26 | /Library/LaunchAgents/com.google.keystone.agent.plist \ 27 | /Library/LaunchAgents/com.oracle.java.Java-Updater.plist \ 28 | /Library/LaunchDaemons/com.puppetlabs.pxp-agent.plist" 29 | 30 | # this list may be unsafe, so if there are issues you can always 31 | # reload them back w/ launchctl load -F $name 32 | additional_items_to_remove="\ 33 | /System/Library/LaunchDaemons/com.apple.systemstats.daily.plist \ 34 | /System/Library/LaunchDaemons/com.apple.systemstatsd.plist \ 35 | /System/Library/LaunchDaemons/com.apple.systemstats.analysis.plist \ 36 | /System/Library/LaunchAgents/com.apple.NowPlayingTouchUI.plist \ 37 | /System/Library/LaunchAgents/com.apple.touchbar.agent.plist \ 38 | /Library/LaunchDaemons/com.crashplan.engine.plist \ 39 | /System/Library/LaunchAgents/com.apple.rcd.plist" 40 | 41 | others="\ 42 | /Library/LaunchDaemons/com.fitbit.galileod.plist \ 43 | /Library/LaunchDaemons/net.tunnelblick.tunnelblick.tunnelblickd.plist \ 44 | " 45 | # note: crash plan is the stupid app RP installs which constantly 46 | # consumes cpu (even when set to do backup in a schedule) and wastes 47 | # lot of resources! 48 | 49 | # normal items 50 | echo "Removing totally unneeded items..." 51 | for name in $items_to_remove; do 52 | if [ -e $name ]; then 53 | echo "Removing $name" 54 | launchctl unload -w $name 55 | fi 56 | done 57 | 58 | # additional items (if needed) 59 | if [[ ! -z $1 && $1 = "--extended" ]]; then 60 | echo "Removing additional items ..." 61 | for name in $additional_items_to_remove; do 62 | if [ -e $name ]; then 63 | echo "Removing $name" 64 | launchctl unload -w $name 65 | fi 66 | done 67 | fi 68 | -------------------------------------------------------------------------------- /macos/say.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # say.sh --- simple wrapper over say 4 | # 5 | # --- DEPRICATED: Please use txt2mp3.sh instead --- 6 | # 7 | # Author: Arul Selvan 8 | # Created: May 18, 2023 9 | # 10 | 11 | # version format YY.MM.DD 12 | version=23.05.18 13 | my_name="`basename $0`" 14 | my_version="`basename $0` v$version" 15 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 16 | options="t:v:h?" 17 | 18 | text="Hello there" 19 | volume=5 20 | cur_vol=0 21 | 22 | # ensure path for cron runs 23 | export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" 24 | 25 | usage() { 26 | cat << EOF 27 | 28 | Usage: $my_name [options] 29 | -t ---> text to say on macOS system speaker [Default: $text] 30 | -v ---> volume to adjust before speaking between 1-100 [Default: $volume] 31 | -h ---> print usage/help 32 | 33 | example: $my_name -v$volume -t "$text" 34 | 35 | EOF 36 | exit 0 37 | } 38 | 39 | # ---------- main -------------- 40 | echo "This script is DEPRICATED, please use txt2mp3.sh in the same directory" 41 | exit 0 42 | 43 | # parse commandline options 44 | while getopts $options opt ; do 45 | case $opt in 46 | v) 47 | volume=$OPTARG 48 | ;; 49 | t) 50 | text="$OPTARG" 51 | ;; 52 | ?|h|*) 53 | usage 54 | ;; 55 | esac 56 | done 57 | 58 | echo "$my_version" > $log_file 59 | 60 | # save current volume to restore, & set new volume 61 | cur_vol=$(osascript -e 'output volume of (get volume settings)') 62 | osascript -e "set volume output volume $volume" 2>&1 | tee -a $log_file 63 | 64 | # emit the text to speaker 65 | echo "$text" | say 2>&1 | tee -a $log_file 66 | 67 | # restore original volume 68 | osascript -e "set volume output volume $cur_vol" 2>&1 | tee -a $log_file 69 | 70 | -------------------------------------------------------------------------------- /macos/smcFanReset.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # smcFanReset.sh 4 | # 5 | # Simple script to use the smc tool to lower (or higher) fan speed by 6 | # forcing fan mode to 'manual' and return it back to 'auto' mode. The 7 | # Reason: Pre 2008 aluminum macbooks sensors sometime instruct fan to 8 | # to go so fast even though the temp is not that high. Only run this 9 | # script if the fan goes crazy fast. It should calm down after this 10 | # script. The smc tool is available at github at link below. 11 | # https://github.com/hholtmann/smcFanControl/tree/master/smc-command 12 | # 13 | # Author: Arul Selvan 14 | # Version: Nov 27, 2014 15 | # 16 | # Note: this must run as 'sudo' especially force fan mode to manual 17 | # 18 | smc=/Users/aselvan/bin/smc 19 | log_file=/Users/kavitha/Desktop/fanspeed.txt 20 | 21 | # 22 | # Read CPU0 temperature 23 | # 24 | echo "Manipulate/trick malfunctioning SMC temp/fan to run properly." > $log_file 25 | echo "Run Time: `date`" >> $log_file 26 | echo "" >> $log_file 27 | 28 | # get current temp 29 | echo "Current temp: " >> $log_file 30 | $smc -k TC0D -r 2>&1 >> $log_file 31 | 32 | # get current speed 33 | echo "Current speed: " >> $log_file 34 | $smc -k F0Ac -r 2>&1 >> $log_file 35 | 36 | # force fan mode to manual 37 | echo "Forcing fan mode to 'manual' ..." >> $log_file 38 | $smc -k "FS! " -w 0001 2>&1 >> $log_file 39 | 40 | # set current speed to 4000 (i.e. python -c "print hex(4000 << 2)" = 3e80) 41 | $smc -k F0Tg -w 3e80 2>&1 >> $log_file 42 | echo "Forced fan to run at 4000rpm, reading value back below..." >> $log_file 43 | $smc -k F0Tg -r 2>&1 >> $log_file 44 | 45 | # reset it back to auto mode 46 | echo "Sleeping for 30 sec for fan to raise or lower speed..." >> $log_file 47 | sleep 30 48 | echo "Now, turning fan mode back to 'auto' ..." >> $log_file 49 | $smc -k "FS! " -w 0000 2>&1 >> $log_file 50 | 51 | echo "All Done" >> $log_file 52 | chmod a+rw $log_file 53 | -------------------------------------------------------------------------------- /macos/spotlight.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # spotlight.sh --- simple wrapper to stop/start the annoyning MacOS spotlight 4 | # 5 | # The spotlight is one of MacOS junk that has a bug (see syslog below) that 6 | # no one knows how to fix. It constantly spews this message flooding syslog 7 | # which is not good for SSD disks and there is no way to stop this madness. 8 | # The only way to remove the service is to undo SIP, remove and turn it back 9 | # on but then a subsequent OS update will enable back this nonsense. This script 10 | # allows to enable/disable w/ out removing the service. 11 | # 12 | # NOTE: turning off and turning on will do the full indexing, even if it is 13 | # up to date! Also, when it is off, macOS outlook native client's search will 14 | # not work, no idea why outlook can't implement search and relying on this 15 | # stupid thing! 16 | # 17 | # Dec 31 04:47:37 lion com.apple.xpc.launchd[1] 18 | # (com.apple.mdworker.shared.0A000000-0700-0000-0000-000000000000[27780]): 19 | # Service exited due to SIGKILL | sent by mds[91] 20 | # 21 | # Author: Arul Selvan 22 | # Version: Dec 31, 2020 23 | # 24 | 25 | my_name=`basename $0` 26 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 27 | spotlight_index_files="/private/var/db/Spotlight /System/Volumes/Data/.Spotlight-V100" 28 | 29 | # ensure path for cron runs 30 | export PATH="/usr/bin:/sbin:/usr/local/bin:$PATH" 31 | 32 | usage() { 33 | echo "Usage: $my_name " 34 | echo " on ---> enable spotlight" 35 | echo " off ---> disable spotlight" 36 | echo " status ---> show status" 37 | echo " reset ---> remove index files, note: 'on' will recreate again" 38 | exit 0 39 | } 40 | 41 | check_root() { 42 | if [ `id -u` -ne 0 ] ; then 43 | echo "[ERROR] you must be 'root' to run this script... exiting." 44 | exit 1 45 | fi 46 | } 47 | 48 | on() { 49 | echo "[INFO] turning on spotlight" | tee -a $log_file 50 | mdutil -a -i on 2>&1 | tee -a $log_file 51 | } 52 | 53 | off() { 54 | mdutil -a -i off 2>&1 | tee -a $log_file 55 | echo "[INFO] turning off spotlight" | tee -a $log_file 56 | } 57 | 58 | reset() { 59 | echo "[INFO] remove spotlight index files" | tee -a $log_file 60 | rm -f $spotlight_index_files 2>&1 | tee -a $log_file 61 | } 62 | 63 | status() { 64 | echo "[INFO] current status of spotlight" | tee -a $log_file 65 | mdutil -a -s 2>&1 | tee -a $log_file 66 | } 67 | 68 | 69 | # ---------- main ---------- 70 | echo "[INFO] `date`: $my_name starting ..." > $log_file 71 | check_root 72 | 73 | case $1 in 74 | on|off|status|reset) "$@" 75 | ;; 76 | *) usage 77 | ;; 78 | esac 79 | 80 | exit 0 81 | -------------------------------------------------------------------------------- /macos/sync_time.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # for MacOS: 4 | # 5 | # sync time w/ time server (runs under root's cron once a day) 6 | # Note: this is needed since we disabled the ntpd daemon which runs in 7 | # a sandbox in MacOS which does not allow reading resolv.conf thereby 8 | # does not sync time. 9 | # 10 | # Author: Arul Selvan 11 | # Version: Sep 5, 2014 12 | # 13 | 14 | log_file="/tmp/sync_time.log" 15 | # ntp client 16 | ntp_client="/usr/bin/sntp -sS" 17 | # use a list of servers so it works regardless of network (work or home) 18 | time_servers="time.apple.com pool.ntp.org" 19 | 20 | echo "Running time script ..." > $log_file 21 | uid=`id -u` 22 | if [ $uid -ne 0 ]; then 23 | echo "Need to run this in sudo" >> $log_file 2>&1 24 | exit 25 | fi 26 | 27 | for time_server in $time_servers; do 28 | /sbin/ping -t30 -c1 -qo $time_server >>$log_file 2>&1 29 | if [ $? -eq 0 ]; then 30 | echo "Sync'ing time w/ server: $time_server" >> $log_file 31 | $ntp_client $time_server >> $log_file 2>&1 32 | exit 33 | fi 34 | done 35 | echo "Unable to reach any of the time servers: $time_servers" >> $log_file 36 | -------------------------------------------------------------------------------- /macos/sysctl.conf: -------------------------------------------------------------------------------- 1 | # 2 | # custom sysctl.conf to tune certain settings on network stack on macOS 3 | # 4 | # Author: Arul Selvan 5 | # Version: Oct 31, 2020 6 | # 7 | 8 | kern.ipc.somaxconn=1024 9 | net.inet.tcp.blackhole=2 10 | net.inet.udp.blackhole=1 11 | net.inet.tcp.mssdflt=1448 12 | net.inet.tcp.recvspace=524288 13 | net.inet.tcp.sendspace=524288 14 | net.inet.tcp.slowstart_flightsize=20 15 | net.inet.tcp.win_scale_factor=4 16 | -------------------------------------------------------------------------------- /macos/sysctl_tune.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | # 3 | # sysctl_tune.sh --- wrapper script to experiment w/ network stack tuning 4 | # 5 | # First run some network performance test i.e. like running speedtest-cli 6 | # or better yet use netperf to get baseline. Then run this script with -s 7 | # option to setup optimal value, and rerun your performance test to see if 8 | # there is any significant improvements, you can then add these settings 9 | # permanently by coping (or appending) the file sysctl.conf in this directory 10 | # to /etc/sysctl.conf and reboot. 11 | # 12 | # Reference/Credit: 13 | # https://rolande.wordpress.com/2020/04/16/performance-tuning-the-network-stack-on-macos-high-sierra-10-13-and-mojave-10-14/ 14 | # 15 | # Author: Arul Selvan 16 | # Version: Oct 31, 2020 17 | # 18 | 19 | my_name=`basename $0` 20 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 21 | options_list="srlh" 22 | 23 | # Note: the default values to reset are from MacOS Catalina 10.15.7 24 | default_settings="kern.ipc.somaxconn=128 net.inet.tcp.blackhole=0 net.inet.tcp.mssdflt=512 net.inet.tcp.recvspace=131072 net.inet.tcp.sendspace=131072 net.inet.tcp.slowstart_flightsize=1 net.inet.tcp.win_scale_factor=3 net.inet.udp.blackhole=0" 25 | 26 | optimized_settings="kern.ipc.somaxconn=1024 net.inet.tcp.blackhole=2 net.inet.tcp.mssdflt=1448 net.inet.tcp.recvspace=524288 net.inet.tcp.sendspace=524288 net.inet.tcp.slowstart_flightsize=20 net.inet.tcp.win_scale_factor=4 net.inet.udp.blackhole=1" 27 | 28 | usage() { 29 | echo "Usage: $my_name [-l] [-s] [-r]" 30 | echo " -l list current values" 31 | echo " -s setup with optimized values" 32 | echo " -r restore default values" 33 | exit 0 34 | } 35 | 36 | check_root() { 37 | if [ `id -u` -ne 0 ] ; then 38 | echo "[ERROR] you must be 'root' to run this script... exiting." | tee -a $log_file 39 | exit 40 | fi 41 | } 42 | 43 | sysctl_list() { 44 | echo "[INFO] listing current sysctl values ..." | tee -a $log_file 45 | for v in $optimized_settings ; do 46 | var=`echo $v|awk -F= '{print $1;}'` 47 | /usr/sbin/sysctl $var 48 | done 49 | exit 50 | } 51 | 52 | sysctl_optimize() { 53 | echo "[INFO] setting optimized sysctl values ..." | tee -a $log_file 54 | for v in $optimized_settings ; do 55 | /usr/sbin/sysctl -w $v 56 | done 57 | exit 58 | } 59 | 60 | sysctl_restore() { 61 | echo "[INFO] restoring optimized sysctl values ..." | tee -a $log_file 62 | for v in $default_settings ; do 63 | /usr/sbin/sysctl -w $v 64 | done 65 | exit 66 | } 67 | 68 | # -------------------------- main ----------------------------- 69 | check_root 70 | echo "[INFO] $my_name starting..." > $log_file 71 | 72 | # process commandline 73 | while getopts "$options_list" opt; do 74 | case $opt in 75 | l) 76 | sysctl_list 77 | ;; 78 | s) 79 | sysctl_optimize 80 | ;; 81 | r) 82 | sysctl_restore 83 | ;; 84 | h) 85 | usage 86 | ;; 87 | \?) 88 | usage 89 | ;; 90 | :) 91 | usage 92 | ;; 93 | esac 94 | done 95 | 96 | usage 97 | -------------------------------------------------------------------------------- /macos/vpns.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # vpns.sh --- wrapper to start VPNSecrure on commandline. The reason for this script 4 | # is because VPNSeure sarts this app using osascript leaving it hanging 5 | # which suckingup more than 15% of CPU! WTF? 6 | # 7 | # Author: Arul Selvan 8 | # Version: Apr 12, 2020 9 | # 10 | 11 | log_file=/tmp/vpns.log 12 | vpns_home="/etc/vpns1.2.4.1" 13 | nwjs_bin="$vpns_home/openvpn.app/Contents/MacOS/nwjs" 14 | 15 | check_root() { 16 | if [ `id -u` -ne 0 ] ; then 17 | echo "[ERROR] you must be 'root' to run this script... exiting." | tee -a $log_file 18 | exit 19 | fi 20 | } 21 | 22 | check_root 23 | echo "[INFO] VPNS commandline..." 24 | 25 | #exev this on this script address space 26 | exec $nwjs_bin > $log_file 2>&1 & 27 | -------------------------------------------------------------------------------- /macos/zap_zoom_ws.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # zap_zoomws.sh --- simple script to remove zooms hidden webservice from your mac 4 | # Author: Arul Selvan 5 | # Version: Jul 13, 2019 6 | # 7 | # Disclaimer: use it at your own risk, I am not responsible for any damage. 8 | 9 | zoomus_related_junk="ZoomOpener RingCentralOpener TelusMeetingsOpener \ 10 | BTCloudPhoneMeetingsOpener OfficeSuiteHDMeetingOpener \ 11 | ATTVideoMeetingsOpener BizConfOpener HuihuiOpener \ 12 | UMeetingOpener ZhumuOpener ZoomCNOpener" 13 | 14 | zoomus_related_junk_dirs="zoomus ringcentralopener telusmeetingsopener \ 15 | btcloudphonemeetingsopener officesuitehdmeetingopener attvideomeetingsopener \ 16 | bizconfopener huihuiopener umeetingopener zhumuopener zoomcnopener" 17 | 18 | log_file="/tmp/zap_zoomws.log" 19 | service_port=19421 20 | service_port_range="19400-19500" 21 | 22 | # get a list of any of the zoom junk or its variants if they are running. 23 | pids=`sudo lsof -nP +c 15 -sTCP:LISTEN -i tcp:$service_port_range|awk 'NR>1 {print $2;}'|uniq`; 24 | 25 | echo "[INFO] zap_zoomws.sh starting" >$log_file 26 | 27 | if [ ! -z "$pids" ] ; then 28 | # attempt to directly kill running zoom induced junk 29 | echo "[INFO] kill runnning zoom variat junk by pid ... " | tee -a $log_file 30 | for pid in $pids ; do 31 | kill -9 $pid 32 | if [ $? -ne 0 ] ; then 33 | echo "[ERROR] unable to kill pid=$pid, check and manually remove!" | tee -a $log_file 34 | else 35 | echo "[INFO] killed the web server at pid=$pid" | tee -a $log_file 36 | fi 37 | done 38 | 39 | # attempt to kill all the zoom induced junk apps by name 40 | echo "[INFO] kill running zoom variant junk by name " | tee -a $log_file 41 | for name in $zoomus_related_junk ; do 42 | pkill $name >> $log_file 2>&1 43 | if [ $? -ne 0 ] ; then 44 | echo "[INFO] $name is not running" >>$log_file 2>&1 45 | else 46 | echo "[ERROR] killed the hidden webservice $name" >> $log_file 2>&1 47 | fi 48 | done 49 | else 50 | echo "[INFO] Doesn't look like zoom & other zoom branded services are currently running."|tee -a $log_file 51 | fi 52 | 53 | 54 | echo "[INFO] removing zoom variant installers to prevent future silent installs." | tee -a $log_file 55 | for name in $zoomus_related_junk_dirs ; do 56 | dir="~/.${name}" 57 | if [ -d $dir ] ; then 58 | echo "[WARN] removing $dir" | tee -a $log_file 59 | rm -rf $dir >> $log_file 2>&1 60 | touch $dir >> $log_file 2>&1 61 | chmod 000 $dir >> $log_file 2>&1 62 | else 63 | echo "[INFO] $dir not found, skipping" >> $log_file 64 | fi 65 | done 66 | 67 | -------------------------------------------------------------------------------- /misl/findmods.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Shell script for finding all the modified files 5 | # 6 | # Author: Arul Selvan 7 | # version: Aug 05, 2003. 8 | # 9 | VERSION="4.3.5" 10 | LOCAL_PATH="/cygdrive/c/src/dspro-$VERSION" 11 | BACKUP_PATH="/cygdrive/c/src/backup/$VERSION" 12 | MOD_LIST_FILE=$BACKUP_PATH/modfiles.lst 13 | 14 | cd $LOCAL_PATH/netw 15 | find . \( -iname \*.cpp -o -iname \*.h -o -iname \*.rc \) -perm 700 -print >$MOD_LIST_FILE 16 | 17 | cd $LOCAL_PATH/dspro 18 | find . \( -iname \*.cpp -o -iname \*.h -o -iname \*.rc \) -perm 700 -print >>$MOD_LIST_FILE 19 | 20 | -------------------------------------------------------------------------------- /misl/graphic_perf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # graphic_perf.sh -- runs glx tools 4 | # 5 | # Author : Arul Selvan 6 | # Version: Dec 2013 7 | export vblank_mode=0 8 | program_name= 9 | 10 | usage() { 11 | echo "Usage: $0 [--gears|--mark]" 12 | exit 13 | } 14 | 15 | # parse commandline args 16 | while [ "$1" ] 17 | do 18 | if [ "$1" = "--gears" ]; then 19 | program_name=/usr/bin/glxgears 20 | break 21 | elif [ "$1" = "--mark" ]; then 22 | program_name=/usr/bin/glmark2 23 | break 24 | else 25 | usage 26 | fi 27 | done 28 | 29 | if [ "$program_name" = "" ]; then 30 | usage 31 | fi 32 | 33 | exec $program_name 34 | -------------------------------------------------------------------------------- /misl/tesla_adapter_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # tesla_adapter_check.sh - check for availability of tesla nema adapter 10-50 5 | # 6 | # Author: Arul Selvan 7 | # Version: Mar 12, 2020 8 | 9 | available_msg="14-50 adapter is possibly available" 10 | email_addr="foo@bar.com" 11 | email_msg="tesla adapter" 12 | 13 | wget -O - -q https://shop.tesla.com/product/gen-2-nema-adapters |grep "value=.* data-sku=\"1099344-10-D"|grep data-uri >/dev/null 2>&1 14 | 15 | if [ $? -eq 0 ] ; then 16 | echo $available_msg 17 | echo $available_msg | mail -s "$email_msg" $email_addr 18 | fi 19 | -------------------------------------------------------------------------------- /pihole/README.md: -------------------------------------------------------------------------------- 1 | # PI-hole (https://github.com/pi-hole) 2 | 3 | ### PI-hole related files 4 | 5 | - #### /block_list.txt 6 | A tiny block list to add to pihole "Adlists" configuration 7 | 8 | -------------------------------------------------------------------------------- /pihole/block_list.txt: -------------------------------------------------------------------------------- 1 | # 2 | # selvans.net --- pihole block list 3 | # 4 | # A tiny block list for pihole (https://github.com/pi-hole) This can be used 5 | # in pihole "Adlists" configuration in addition to the standard lists to block 6 | # specific hosts. 7 | # 8 | # Author: Arul Selvan 9 | # Version History: 10 | # Feb 16, 2023 --- Original version 11 | # Jan 11, 2024 --- Moved to my gitrepo https://raw.githubusercontent.com/aselvan/scripts/master/pihole/block_list.txt 12 | # May 8 , 2024 --- Added weird citi.com content providers, oracle co-browsing we dont care about. 13 | # 14 | 15 | # double click 16 | 0.0.0.0 pubads.g.doubleclick.net 17 | 0.0.0.0 securepubads.g.doubleclick.net 18 | 19 | # Free online game 20 | 0.0.0.0 yad.com 21 | 22 | # amplifyapp.com hosts bunch of phising/malware zap it 23 | 0.0.0.0 amplifyapp.com 24 | 25 | # strange websites citi.com uses for some "unknown" content 26 | # my reddit post: https://www.reddit.com/r/Domains/comments/1cmpg48/info_on_domains_behind_domains_by_proxy_service/ 27 | 0.0.0.0 1.a79ab95c1589a13f8a4cab612bc71f9f7.com 28 | 0.0.0.0 1.b406929acabac9b095f124c81bdfcf57f.com 29 | 0.0.0.0 1.c81358859121583b7adf2ace89cb39f44.com 30 | 31 | # cobrowsing used by chase.com possibly others, dont give a crap about this, zap it 32 | # See: https://docs.oracle.com/en/cloud/paas/content-cloud/creating-experiences/cobrowse.html 33 | 0.0.0.0 public.cobrowse.oraclecloud.com 34 | 35 | # reddit ad image preview 36 | 0.0.0.0 preview.redd.it 37 | 0.0.0.0 external-preview.redd.it 38 | -------------------------------------------------------------------------------- /python_modules/myutils_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # myutils_test.py -- quick and dirty test harness for myutils.py module 4 | # 5 | # Author: Arul Selvan 6 | # Version: May 16, 2023 7 | # 8 | 9 | import sys 10 | import argparse 11 | import os 12 | import pathlib 13 | sys.path.append(os.path.join(os.path.dirname(__file__),'../python_modules')) 14 | import myutils 15 | import time 16 | 17 | version="23.05.17" 18 | my_path=__file__ 19 | my_name=myutils.getMyName(my_path) 20 | my_desc=my_name+f" v{version} -- Test harness for the myutils.py module" 21 | 22 | 23 | # test commandline parser (must be the first one so we can setup logger) 24 | parser = argparse.ArgumentParser(parents=[myutils.getArgParser()], 25 | description=my_desc,prog=my_name,conflict_handler="resolve") 26 | parser.add_argument("-i", "--integer", dest="counter",help="integer option with a list", default="0", choices=[0,1,2], type=int) 27 | parser.add_argument("-d", "--data", dest="animal", help="string option with a list", choices=['cow','goat'], type=str) 28 | parser.add_argument("-p", "--path", dest="path", help="path option, also a required", type=pathlib.Path,required=True) 29 | parser.add_argument("-f", "--file", dest="fname", help="filename option", type=str) 30 | args=parser.parse_args() 31 | 32 | # test logger 33 | logger = myutils.getLogger(myutils.getLogFilename(my_path),args.logLevel) 34 | logger.info("this is info message") 35 | logger.warning("this is warn message") 36 | logger.error("this is error message") 37 | logger.debug("debug message") 38 | 39 | # validate path 40 | if not os.path.isdir(args.path): 41 | logger.error(str(args.path)+": is not a valid path!") 42 | 43 | # if filename provided, validate 44 | if (args.fname): 45 | if not os.path.isfile(args.fname): 46 | logger.error(args.fname+": is not a valid file!") 47 | 48 | #parser.print_help() 49 | #help(myutils) 50 | 51 | # test the connectivity function 52 | logger.debug(f"Connectivity: {myutils.checkConnectivity()}") 53 | 54 | # test mail 55 | m = myutils.SendMail("foo@bar.com", "python test mail") 56 | m.setBody("mail body text for python text mail") 57 | logger.debug (m) 58 | #m.send() 59 | 60 | # getIP 61 | logger.info("My IP: "+myutils.getIP("en1")) 62 | 63 | # test root 64 | myutils.requireRoot() 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /qemu/README.qemu: -------------------------------------------------------------------------------- 1 | # 2 | # README.qemu 3 | # 4 | # Author: Arul Selvan 5 | # Version: Sep 4, 2020 6 | 7 | 8 | # Misl howto's for qemu (for macOS, should work for Linux as well) 9 | 10 | 11 | 1. Create a fresh new install 12 | 13 | 1.1 qemu-img create -f qcow2 os.qcow2 8G 14 | 1.2 qemu-system-x86_64 -smp 2 -m 4096 -vga std -cdrom os_cd_image.iso -accel hvf -cpu -nic user -machine pc-q35-2.10 -drive file=os.qcow2,if=virtio 15 | 1.3 Install from CD rom 16 | 1.4 Run with qemu-system-x86_64 -smp 2 -m 4096 -vga std -hda os.qcow2 -accel hvf -cpu -nic user -machine pc-q35-2.10 17 | 18 | 2. How to create snapshot copy from original 19 | 20 | qemu-img create -f qcow2 -b original.qcow2 snapshot.qcow2 21 | 22 | 3. Convert Virtualbox VDI|VMDK to qcow2 23 | 24 | # extract the OVA file that would extract the vmdk 25 | tar -xvf myimage.ova 26 | 27 | # convert a VMDK to qcow2 28 | qemu-img convert myimage.vmdk myimage.qcow2 -O qcow2 29 | 30 | # convert a VDI to qcow2 (can't get it to work) 31 | qemu-img convert -f vdi -O qcow2 myimage.vdi myimage.qcow2 32 | 33 | # check the image 34 | qemu-img info myimage.qcow2 35 | 36 | 4. Compress and make the image smaller 37 | 38 | 4.1. start the guest vm and run dfrag, and write 0's to unused space. In windows run 39 | sdelete -c c: and sdelete -z c: 40 | 41 | 4.2. run the following 42 | qemu-img convert -c -f qcow2 original.qcow2 -O qcow2 compressed.qcow2 43 | 44 | 5. Resize the qcow2 45 | 46 | 5.1 Shutdown the VM 47 | 5.2 run the following 48 | sudo qemu-img resize original.qcow2 +8G # add 8G more 49 | # 50 | # NOTE: MacOS BigSur problems 51 | # updated: Jan 30, 2021 [ Credit: https://sizeof.cat/post/qemu-and-macos-bigsur/ ] 52 | If you try to run QEMU under macOS Big Sur with the -machine accel=hvf flag (basically 53 | with Apple’s Hypervisor Framework) you’ll get one ugly error; every time hv_vm_create() 54 | runs it returns an HV_ERROR. The reason is that the com.apple.vm.hypervisor 55 | entitlement (used in macOS 10.15) has been deprecated and replaced by 56 | com.apple.security.hypervisor. You need to sign your binary with the correct 57 | entitlement. Run the command below with the entitlements.xml file found in this dir 58 | 59 | $ codesign -s - --entitlements entitlements.xml --force /usr/local/bin/qemu-system-x86_64 60 | -------------------------------------------------------------------------------- /qemu/entitlements.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.hypervisor 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /raspberrypi/README.md: -------------------------------------------------------------------------------- 1 | # raspberrypi 2 | 3 | ### Various tools/scripts/howtos to build a image for Pi to be used as IoT device or pentest device. 4 | 5 | - #### /README.raspberrypi 6 | Steps to build thin image for Pi Zero with wifi enabled so you can use the Pi anywhere like in a car 7 | 8 | - #### /README.opencanary 9 | Steps to install and configure opencanary (security honypot device) on your Pi. 10 | 11 | - #### /README.metasploit 12 | Steps to install and configure metasploit pentest tools on your pi image above. 13 | 14 | - #### /wifi_event_run.sh 15 | Automation script to run on scheduler to capture wpa_supplicant connect events i.e. when your Pi connects to a new wifi access point or disconnects. This can be used to take any action on your pi device. 16 | 17 | - #### /periodic_run.sh 18 | Automation script to run when Pi boots to perform bootup tasks as needed. 19 | 20 | -------------------------------------------------------------------------------- /raspberrypi/README.metasploit: -------------------------------------------------------------------------------- 1 | # 2 | # Steps intall/setup/run metasploit 3 | # 4 | # 5 | # Author: Arul Selvan 6 | # Version: Aug 30, 2020 7 | # 8 | 9 | 10 | # run it as root (metasploit will complain about mulitiuser) since there is only one user. 11 | sudo su 12 | 13 | # install dependencies. 14 | apt-get install rbenv 15 | rbenv rehash 16 | apt-get install git ruby ruby-pg postgresql-common \ 17 | libpq-dev libpcap0.8 bundler \ 18 | ruby-pcaprub libpcap0.8 libpcap0.8-dev libsqlite3-dev 19 | 20 | # configure git to get msfupdate script to work 21 | git config --global user.name "Your Name" 22 | git config --global user.email "yourname@yourdomain.com" 23 | 24 | # we are installing /opt/metasploit-framework 25 | cd /opt 26 | git clone git://github.com/rapid7/metasploit-framework 27 | cd metasploit-framework 28 | ./msfupdate 29 | bundle install 30 | 31 | # finally to run 32 | ./msfconsole 33 | -------------------------------------------------------------------------------- /raspberrypi/README.opencanary: -------------------------------------------------------------------------------- 1 | # 2 | # Steps intall/setup/run opencanary 3 | # 4 | # 5 | # Author: Arul Selvan 6 | # Version: Aug 30, 2020 7 | # 8 | 9 | # 10 | # Install PI image 11 | # 12 | # First follow the README.raspberypi at link below to install your image to raspberrypi 13 | # 14 | # https://github.com/aselvan/scripts/blob/master/raspberrypi/README.raspberrypi 15 | # 16 | 17 | # Once your pi is up and running, ssh into it and follow the steps below 18 | 19 | # run it as root 20 | sudo su 21 | 22 | # install 23 | apt-get update; apt-get upgrade --fix-missing 24 | apt-get install python-dev python-pip python-virtualenv build-essential libssl-dev libffi-dev 25 | 26 | # install a separate python env for opencanary 27 | cd /opt/ 28 | virtualenv -p /usr/bin/python3 opencanary 29 | pip3 install 'setuptools<45.0.0' 30 | pip install rdpy RDP SNMP 31 | . opencanary/bin/activate 32 | pip3 install opencanary 33 | 34 | # copy the configurations 35 | mkdir /etc/opencanaryd 36 | cp /etc/opencanaryd/. 37 | (or) 38 | opencanary/bin/opencanaryd --copyconfig # this creates ~/.opencanary.conf now copy it to /etc/opencanaryd/ 39 | 40 | # you can run the following on a local.rc or @reboot cron entry 41 | /opt/opencanary/bin/opencanaryd --start 42 | 43 | -------------------------------------------------------------------------------- /raspberrypi/README.pibackup: -------------------------------------------------------------------------------- 1 | # 2 | # Steps to backup raspberyPI image. 3 | # 4 | # Follow this steps to backup the raspberrypi to a image for use in the case 5 | # the SD card went bad. This image can be copied to a brand new SD card to bring 6 | # back the PI instantly. 7 | # 8 | # NOTE: The new SD card must be least the current size of the broken SD card or 9 | # larger size. 10 | # 11 | # Author: Arul Selvan 12 | # Version: Aug 30, 2020 13 | # 14 | # Ref: https://www.tomshardware.com/how-to/back-up-raspberry-pi-as-disk-image 15 | # Credit: https://github.com/Drewsif/PiShrink --- forked to my github https://github.com/aselvan/PiShrink) 16 | 17 | # 18 | # Steps 19 | # 20 | 1. wget https://github.com/aselvan/PiShrink/blob/master/pishrink.sh 21 | 2. Attach a external USB to PI4 (should be same size or bigger than current running SD card) 22 | 3. run lsblk to get the PI sd card's block device we need [typically it should be /dev/mmcblk0] 23 | 4. sudo dd if=/dev/mmcblk0 of=/pi4backup.img bs=1M 24 | 5. copy the pi4backup.img to a linux host 25 | 6. run "sudo pishrink.sh -z pi4backup.img pi4backup_shrinked.img" 26 | 7. Finally, save the shrinked image as your PI backup image. 27 | 28 | # 29 | # PS: If you dont have physical access to your PI4, you can replace the step #4 with the 30 | # following and ignore step#2 31 | # 32 | 4. ssh root@pi "dd if=/dev/mmcblk0 bs=32M" | dd of=pi4backup.img 33 | 34 | -------------------------------------------------------------------------------- /raspberrypi/cmdline.txt: -------------------------------------------------------------------------------- 1 | console=serial0,115200 console=tty1 root=PARTUUID=deeae0de-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2,g_ether quiet splash plymouth.ignore-serial-consoles 2 | -------------------------------------------------------------------------------- /raspberrypi/dhcpcd.conf: -------------------------------------------------------------------------------- 1 | # A sample configuration for dhcpcd. 2 | # See dhcpcd.conf(5) for details. 3 | 4 | # Allow users of this group to interact with dhcpcd via the control socket. 5 | #controlgroup wheel 6 | 7 | # Inform the DHCP server of our hostname for DDNS. 8 | hostname 9 | 10 | # Use the hardware address of the interface for the Client ID. 11 | clientid 12 | # or 13 | # Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361. 14 | # Some non-RFC compliant DHCP servers do not reply with this set. 15 | # In this case, comment out duid and enable clientid above. 16 | #duid 17 | 18 | # Persist interface configuration when dhcpcd exits. 19 | persistent 20 | 21 | # Rapid commit support. 22 | # Safe to enable by default because it requires the equivalent option set 23 | # on the server to actually work. 24 | option rapid_commit 25 | 26 | # A list of options to request from the DHCP server. 27 | option domain_name_servers, domain_name, domain_search, host_name 28 | option classless_static_routes 29 | # Respect the network MTU. This is applied to DHCP routes. 30 | option interface_mtu 31 | 32 | # Most distributions have NTP support. 33 | #option ntp_servers 34 | 35 | # A ServerID is required by RFC2131. 36 | require dhcp_server_identifier 37 | 38 | # Generate SLAAC address using the Hardware Address of the interface 39 | #slaac hwaddr 40 | # OR generate Stable Private IPv6 Addresses based from the DUID 41 | slaac private 42 | 43 | # Example static IP configuration: 44 | #interface eth0 45 | #static ip_address=192.168.0.10/24 46 | #static ip6_address=fd51:42f8:caae:d92e::ff/64 47 | #static routers=192.168.0.1 48 | #static domain_name_servers=192.168.0.1 8.8.8.8 fd51:42f8:caae:d92e::1 49 | 50 | # It is possible to fall back to a static IP if DHCP fails: 51 | # define static profile 52 | #profile static_eth0 53 | #static ip_address=192.168.1.23/24 54 | #static routers=192.168.1.1 55 | #static domain_name_servers=192.168.1.1 56 | 57 | # fallback to static profile on eth0 58 | #interface eth0 59 | #fallback static_eth0 60 | interface eth0 61 | static ip_address=192.168.1.13/24 62 | static routers=192.168.1.1 63 | static domain_name_servers= 64 | -------------------------------------------------------------------------------- /raspberrypi/periodic_run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # periodic_run.sh 4 | # 5 | # This script is setup as cronjob to run every 5 minutes. It should try and 6 | # complete under 5 minutes and if it takes longer, the cron interval should 7 | # be adjusted; but cronjob is protected from mulitple invocation anyways. 8 | # 9 | # Note: copy this script to /root/scripts or other place refered in crontab path 10 | # 11 | # Author: Arul Selvan 12 | # Version: Jul 4, 2020 13 | # 14 | 15 | # current version: YY.MM.DD 16 | version=22.07.17 17 | 18 | # google dns for validating connectivity 19 | gdns=8.8.8.8 20 | my_name="`basename $0` v$version" 21 | log_file="/var/log/$(echo $my_name|cut -d. -f1).log" 22 | home_public_ip=`dig +short selvans.net @$gdns` 23 | publish_ip_url_file="/root/.publish_ip_url" 24 | 25 | 26 | pi_is_home() { 27 | echo "[INFO] PI is home!" >> $log_file 28 | 29 | # TODO: copy the tesla dashcam data here... (need to figure out how often we do this) 30 | 31 | # update our git to get all the code with new release so pi is updated with newly released code 32 | (cd /root/scripts; /usr/bin/git pull 2>&1 >> $log_file) 33 | } 34 | 35 | pi_is_not_home() { 36 | 37 | echo "[INFO] PI somewhere other than home!" >> $log_file 38 | 39 | # TODO: do any other stuff we want here. 40 | } 41 | 42 | # ---------- main --------------- 43 | echo "[INFO] $my_name starting at `date`..." >> $log_file 44 | 45 | # first check if we got connectivity. 46 | /bin/ping -t30 -c3 -q $gdns >/dev/null 2>&1 47 | if [ $? -ne 0 ] ; then 48 | echo "[WARN] We dont have connectivity. force dhcpd? or force wpa_supplicant to try again?" >> $log_file 49 | # for now, exit; will figureout how to force wlan to reconnect. 50 | exit 51 | fi 52 | 53 | # we got connectivity, see if we are at home (NOTE: reads the router IP from env variable) 54 | if [ -z "${HOME_PUBLIC_IP}" ] ; then 55 | echo "[INFO] HOME_PUBLIC_IP not set, assuming this is us (selvans.net) " >> $log_file 56 | else 57 | home_public_ip=${HOME_PUBLIC_IP} 58 | fi 59 | 60 | # find pi's egress IP 61 | my_ip=`dig +short myip.opendns.com @resolver1.opendns.com` 62 | my_ip=`curl -s ifconfig.me/ip` 63 | echo "[INFO] `hostname` public IP is: $my_ip" >> $log_file 64 | 65 | if [ ${home_public_ip} = ${my_ip} ] ; then 66 | pi_is_home 67 | else 68 | pi_is_not_home 69 | fi 70 | 71 | # save the last location info 72 | if [ -f $HOME/last_location.txt ] && [ -f $publish_ip_url_file ] ; then 73 | latlon_url="https://www.google.com/maps?q=`cat $HOME/last_location.txt`" 74 | publish_ip_url=`cat $publish_ip_url_file` 75 | url="$publish_ip_url?host=tesla&ip=$latlon_url" 76 | echo "[INFO] Publishing to: $url" >> $log_file 77 | curl -w "\n" -s $url >> $log_file 2>&1 78 | fi 79 | 80 | echo "[INFO] nothing more for now, exiting" >> $log_file 81 | 82 | # TODO: more stuff later ... 83 | 84 | -------------------------------------------------------------------------------- /raspberrypi/pizero-logrotate: -------------------------------------------------------------------------------- 1 | # 2 | # pizero-logrotate 3 | # 4 | # Log rotate for all the scripts we have for raspberrypi such as periodic_run.sh, 5 | # wifi_event_run.sh etc. 6 | # 7 | # Note: copy this file to /etc/logrotate.d/ 8 | # 9 | # Author: Arul Selvan 10 | # Version: Aug 8, 2020 11 | # 12 | 13 | /var/log/periodic_run.log { 14 | copytruncate 15 | weekly 16 | rotate 4 17 | compress 18 | delaycompress 19 | missingok 20 | size 5M 21 | } 22 | 23 | /var/log/wifi_event_run.log { 24 | copytruncate 25 | weekly 26 | rotate 4 27 | compress 28 | delaycompress 29 | missingok 30 | size 5M 31 | } 32 | 33 | /var/log/poweron_run.log { 34 | copytruncate 35 | weekly 36 | rotate 4 37 | compress 38 | delaycompress 39 | missingok 40 | size 5M 41 | } 42 | -------------------------------------------------------------------------------- /raspberrypi/root.crontab: -------------------------------------------------------------------------------- 1 | # 2 | # root crontab for pizero 3 | # 4 | # Author: Arul Selvan 5 | # Version: Jul 4, 2020 6 | # 7 | 8 | # ensure we have everything in our path 9 | PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 10 | 11 | # setup a env variable for your home public IP which is used to 12 | # detect if PI is home. Make sure you set this correctly as this is 13 | # obviously cloudflare dns :) 14 | #HOME_PUBLIC_IP=1.1.1.1 15 | 16 | # IFTTT creds for use. set this to your key and make sure you have 17 | # an event defined 'pizero' which is what will be used by the script 18 | #IFTTT_KEY=abcde 19 | 20 | # punch SSH port on firewall for our external IPs to ssh into PI 21 | # setup a port you want to ensure for ssh access, setup something other than 22 22 | # but don't forget to change /etc/ssh/sshd_config to enable that port on pi 23 | #EXTERNAL_SSH_PORT=22 24 | 25 | # setup list of exteral IPs you want firewal to allow so you can ssh into PI 26 | # note: this assumes you had configured firewall on PI (ufw is assumed) 27 | #EXTERNAL_IP_LIST="192.168.1.1 192.168.1.2" 28 | 29 | # Power on script i.e. when tesla wakes up the hub is powered so our PI 30 | # should be booting. 31 | # 32 | # Note: need to send to background to let PI continue to boot 33 | @reboot /usr/bin/flock -w10 /tmp/poweron_run.lock /root/scripts/raspberrypi/poweron_run.sh >/dev/null 2>&1 & 34 | 35 | # Run every 10 minutes. This script should try and complete under 5 minutes. 36 | # if it takes longer, the cron interval should be adjusted but it is protected from 37 | # mulitple invocation anyways. 38 | # 39 | # Purpose: Can be used to do general purpose stuff like check wifi/connectivity 40 | # or send message via IFTTT etc. 41 | */10 * * * * /usr/bin/flock -w10 /tmp/periodic_run.lock /root/scripts/raspberrypi/periodic_run.sh >/dev/null 2>&1 42 | 43 | # Run every 15 minutes. 44 | # Purpose: check for free_wifi and connect to it 45 | */15 * * * * /usr/bin/flock -w10 /tmp/free_wifi.lock /root/scripts/macos/free_wifi.sh -i wlan0 >/tmp/free_wifi.log 2>&1 46 | 47 | -------------------------------------------------------------------------------- /raspberrypi/wpa_supplicant.conf: -------------------------------------------------------------------------------- 1 | # 2 | # wpa_supplicant.conf --- wireless default file for rasberryPI 3 | # 4 | # Before flashing the PI image, copy this file (after seeting the right values) to the 5 | # boot directory of the PI image. 6 | # 7 | # note: the psk can be plain but not recomended, use wpa_passphrase to generate a hash 8 | # and use the hash instead. macOS don't have wpa_passphrase so you kinda have to use 9 | # a linux box to get the hash computed. #NOTE#: encrypted hash should not be in "" like 10 | # the plain password 11 | # 12 | # TODO: 13 | # * define additional network as needed 14 | # * change the priority to suite your need i.e. higher number for preference. 15 | # 16 | # Generate encrypted hash: wpa_passphrase "MY_HOME_MAIN_SSID" 17 | # the wpa_passphrase is available on PI or any linux distro. 18 | # 19 | # Author: Arul Selvan 20 | # Version: Juk 3, 2020 21 | # 22 | 23 | ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev 24 | update_config=1 25 | country=US 26 | 27 | # agressive scanning (experiment with this) 28 | # can every 30 seconds when the signal is weak (below -80), and every 3600 seconds otherwise 29 | #bgscan="simple:30:-80:3600" 30 | 31 | 32 | # home (main) 33 | network={ 34 | ssid="MY_HOME_MAIN_SSID" 35 | psk="MY_HOME_MAIN_PSK" 36 | priority=200 37 | id_str="MY_HOME_MAIN_SSID" 38 | } 39 | 40 | # home (alternate) 41 | network={ 42 | ssid="MY_HOME_ALTERNATE_SSID" 43 | psk="MY_HOME_ALTERNATE_PSK" 44 | priority=100 45 | id_str="MY_HOME_ALTERNATE_SSID" 46 | } 47 | 48 | # if you are a Spectrum (formerly Timewarner) customer there are lot of wifi spots 49 | # available you could use your login to hop on those. 50 | 51 | network={ 52 | ssid="SpectrumWiFi" 53 | psk=xxxxxxxxxxxxxxx 54 | priority=99 55 | id_str="SpectrumWiFi" 56 | } 57 | 58 | network={ 59 | ssid="SpectrumWiFi Plus" 60 | psk=xxxxxxxxxxxxxxx 61 | priority=98 62 | id_str="SpectrumWiFi Plus" 63 | } 64 | 65 | # 66 | # finally, if you are good w/ any open-wifi it can be setup like so below. 67 | # 68 | # 69 | network={ 70 | key_mgmt=NONE 71 | priority=-999 72 | id_str="unsecured" 73 | } 74 | -------------------------------------------------------------------------------- /security/gpg_backup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # gpg_backup.sh --- Script to backup or referesh PGP keys. 4 | # 5 | # NOTE: this is for my personal use but feel free to copy/modify for your use. 6 | # 7 | # Description: 8 | # exports ascii version of all 3 keys (home, work, yubikey,yubikey2, usbc) to 9 | # local disk as well as update key servers. 10 | # 11 | # Additional info: 12 | # Both yubi and yubi2 (for both old and new keys) are just a pointer in 13 | # the ~/.gnupg files since the original is imported to yubikeys. We got the 14 | # original keys saved with *_master.asc, however for key1(yubi) we may have 15 | # lost it since we did not backup but the yubi2 is backed up which can be written 16 | # back to yubi (key1) so we have both in sync. When listing keys in gpg you 17 | # will see '>' sign in front of keys that are really pointers. 18 | # 19 | # Author: Arul Selvan 20 | # Version: Feb 17, 2012 21 | 22 | my_name=`basename $0` 23 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 24 | key_home="${HOME}/data/personal/keys/pgp-keys" 25 | keyservers="keys.gnupg.net keyserver.ubuntu.com keys.openpgp.org" 26 | keys="0x451A1B6C 0xF81609CB 0x6675D56A 0x0E2A2DE0 0x2D511E41" 27 | key_kavitha="0xD022A025" 28 | key_deepak="0x091CB3D0" 29 | 30 | public_template="${key_home}/Arul_Selvan_GPG_public_" 31 | private_template="${key_home}/Arul_Selvan_GPG_private_" 32 | 33 | referesh() { 34 | echo "[INFO] Refreshing key servers..." | tee -a $log_file 35 | for ksrv in $keyservers; do 36 | gpg --keyserver $ksrv --send-keys $keys $key_kavitha $key_deepak 2>&1 | tee -a $log_file 37 | done 38 | } 39 | 40 | backup() { 41 | echo "[INFO] Backing up ascii version of private and public keys..." | tee -a $log_file 42 | if [ ! -d $key_home ]; then 43 | echo "[ERROR] key home directory '$key_home' is an invalid/non-existent path... exiting" | tee -a $log_file 44 | exit 45 | fi 46 | 47 | #all 48 | #gpg -a --export > ${public_template}all.asc 49 | #gpg -a --export-secret-keys > ${private_template}all.asc 50 | 51 | # Backup Arul's keys 52 | for key in $keys; do 53 | echo "[INFO] exporting $key to file ${public_template}${key}.asc and ${private_template}${key}.asc" | tee -a $log_file 54 | gpg -a --export $key > ${public_template}${key}.asc 55 | gpg -a --export-secret-keys $key > ${private_template}${key}.asc 56 | done 57 | 58 | # backup Deepak & Kavitha's 59 | gpg -a --export $key_kavitha > ${key_home}/Kavitha_Selvan_GPG_public_${key_kavitha}.asc 60 | gpg -a --export-secret-keys $key_kavitha > ${key_home}/Kavitha_Selvan_GPG_private_${key_kavitha}.asc 61 | 62 | gpg -a --export $key_deepak > ${key_home}/Deepak_Selvan_GPG_public_${key_deepak}.asc 63 | } 64 | 65 | usage() { 66 | echo "Usage: $my_name " 67 | exit 0 68 | } 69 | 70 | # ------------------ main ---------------------- 71 | if [ $# -eq 0 ]; then 72 | usage 73 | fi 74 | 75 | echo "[INFO] `date`: $my_name starting ..." > $log_file 76 | case $1 in 77 | backup) 78 | backup 79 | ;; 80 | referesh) 81 | referesh 82 | ;; 83 | *) 84 | usage 85 | ;; 86 | esac 87 | 88 | -------------------------------------------------------------------------------- /security/list_url_redirects.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # list_url_redirects.sh --- Recursively list redirects on a URL 4 | # 5 | # 6 | # Author: Arul Selvan 7 | # Created: Apr 22, 2025 8 | # 9 | # Version History: 10 | # Apr 23, 2025 --- Orginal version 11 | # 12 | 13 | # version format YY.MM.DD 14 | version=25.04.23 15 | my_name="`basename $0`" 16 | my_version="`basename $0` v$version" 17 | my_title="Recursively list redirects on a URL" 18 | my_dirname=`dirname $0` 19 | my_logfile="/tmp/$(echo $my_name|cut -d. -f1).log" 20 | default_scripts_github=$HOME/src/scripts.github 21 | scripts_github=${SCRIPTS_GITHUB:-$default_scripts_github} 22 | 23 | # commandline options 24 | options="u:vh?" 25 | 26 | url="" 27 | redirect_list=() 28 | 29 | usage() { 30 | cat << EOF 31 | $my_name --- $my_title 32 | 33 | Usage: $my_name [options] 34 | -u ---> URL to check for all recursive redirects 35 | -v ---> enable verbose, otherwise just errors are printed 36 | -h ---> print usage/help 37 | 38 | example: 39 | $my_name -u "https://blly.ink/askdoctors" 40 | 41 | EOF 42 | exit 0 43 | } 44 | 45 | # ------------------------------- main ------------------------------- 46 | # First, make sure scripts root path is set, we need it to include files 47 | if [ ! -z "$scripts_github" ] && [ -d $scripts_github ] ; then 48 | # include logger, functions etc as needed 49 | source $scripts_github/utils/logger.sh 50 | source $scripts_github/utils/functions.sh 51 | else 52 | echo "SCRIPTS_GITHUB env variable is either not set or has invalid path!" 53 | echo "The env variable should point to root dir of scripts i.e. $default_scripts_github" 54 | echo "See INSTALL instructions at: https://github.com/aselvan/scripts?tab=readme-ov-file#setup" 55 | exit 1 56 | fi 57 | # init logs 58 | log.init $my_logfile 59 | 60 | # parse commandline options 61 | while getopts $options opt ; do 62 | case $opt in 63 | u) 64 | url="$OPTARG" 65 | ;; 66 | v) 67 | verbose=1 68 | ;; 69 | ?|h|*) 70 | usage 71 | ;; 72 | esac 73 | done 74 | 75 | if [ -z $url ] ; then 76 | log.error "Missing arguments. Need URL, see usage below" 77 | usage 78 | fi 79 | 80 | # Use a loop to trace redirects 81 | current_url=$url 82 | while true; do 83 | # Get the headers and fetch the "Location" value (next redirect) 84 | next_url=$(curl -s -D - -o /dev/null "$current_url" | awk '/^Location:/ {print $2}' | tr -d '\r') 85 | 86 | # Break if there's no "Location" (no more redirects) 87 | if [[ -z "$next_url" ]]; then 88 | break 89 | fi 90 | 91 | # Save the next URL into the list 92 | redirect_list+=("$next_url") 93 | 94 | # Update the URL to the next one 95 | current_url=$next_url 96 | done 97 | 98 | # Output all intermediate URLs 99 | order=1 100 | log.stat "Redirect chain order: " 101 | log.stat " ${order}. ---> $url" 102 | for redirect in "${redirect_list[@]}"; do 103 | ((order++)) 104 | log.stat " ${order}. ---> $redirect" 105 | done 106 | -------------------------------------------------------------------------------- /security/pwned_password.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 0) { 46 | echo "### WARNING ### Your password is FOUND $count times!\n"; 47 | } 48 | else { 49 | echo "### CONGRATS ### your password is NOT found!\n"; 50 | } 51 | -------------------------------------------------------------------------------- /security/vpnsecure/openvpn_down.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # openvpn_down.sh --- called by openVPN when VPN is teared down. 4 | # 5 | # Purpose: When you run openVPN (under the hood, many VPN vendor software run openVPN), you 6 | # may end up going to your original resolver leaking your DNS queries. This script 7 | # works along with openvpn_up.sh to set/reset the DNS servers. It will be called 8 | # by openVPN after tear down of VPN tunnel to restore your original DNS. This 9 | # script is referenced in openVPN config file: vpnsecure.ovpn 10 | # 11 | # Note: As of now, this script only works on macOS, need to update to work on Linux later. 12 | # 13 | # See: vpnsecure.ovpn 14 | # See: openvpn_up.sh 15 | # 16 | # 17 | # Author: Arul Selvan 18 | # Created: Aug 15, 2022 19 | # 20 | 21 | # version format YY.MM.DD 22 | version=23.03.10 23 | my_name="`basename $0`" 24 | my_version="`basename $0` v$version" 25 | host_name=`hostname` 26 | os_name=`uname -s` 27 | verbose=0 28 | cmdline_args=`printf "%s " $@` 29 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 30 | dns_save_file="$HOME/openvpn_dns_save.log" 31 | domain_save_file="$HOME/openvpn_domain_save.log" 32 | primary_svc="" 33 | 34 | # ensure path for cron runs 35 | export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" 36 | 37 | write_log() { 38 | local msg_type=$1 39 | local msg=$2 40 | 41 | # log info type only when verbose flag is set 42 | if [ "$msg_type" == "[INFO]" ] && [ $verbose -eq 0 ] ; then 43 | return 44 | fi 45 | 46 | echo "$msg_type $msg" >> $log_file 47 | } 48 | init_log() { 49 | if [ -f $log_file ] ; then 50 | rm -f $log_file 51 | fi 52 | write_log "[STAT]" "$my_version: starting at `date +'%m/%d/%y %r'` ..." 53 | write_log "[STAT]" "cmdline: $cmdline_args" 54 | } 55 | 56 | restore_dns() { 57 | 58 | if [ ! -e $dns_save_file ] ; then 59 | write_log "[ERROR]" "missing save DNS file ($dns_save_file)" 60 | return 61 | fi 62 | 63 | write_log "[STAT]" "restoring saved DNS '`cat $dns_save_file`'" 64 | 65 | # restore dns and domain 66 | scutil << EOF 67 | open 68 | d.init 69 | d.add ServerAddresses * `cat $dns_save_file` 70 | d.add DomainName `cat $domain_save_file` 71 | set State:/Network/Service/${primary_svc}/DNS 72 | quit 73 | EOF 74 | } 75 | 76 | # ----------- main ------------- 77 | init_log 78 | # as of now just macOS supported. Need to add Linux soon. 79 | if [ $os_name != "Darwin" ] ; then 80 | write_log "[WARN] this os '$os_name' is currently not supported!" 81 | exit 1 82 | fi 83 | 84 | # find the primiary svc 85 | primary_svc=$( (scutil | grep PrimaryService | sed -e 's/.*PrimaryService : //')<< EOF 86 | open 87 | get State:/Network/Global/IPv4 88 | d.show 89 | quit 90 | EOF 91 | ) 92 | 93 | # restored saved dns and domain name when VPN is 94 | restore_dns 95 | 96 | -------------------------------------------------------------------------------- /security/vpnsecure/other_servers.txt: -------------------------------------------------------------------------------- 1 | remote at2.isponeder.com 1191 2 | remote au2.isponeder.com 1191 3 | remote au3.isponeder.com 1191 4 | remote be1.isponeder.com 1191 5 | remote be2.isponeder.com 1191 6 | remote ca1.isponeder.com 1191 7 | remote ca2.isponeder.com 1191 8 | remote ch1.isponeder.com 1191 9 | remote de1.isponeder.com 1191 10 | remote de2.isponeder.com 1191 11 | remote de3.isponeder.com 1191 12 | remote de4.isponeder.com 1191 13 | remote de5.isponeder.com 1191 14 | remote de6.isponeder.com 1191 15 | remote dk3.isponeder.com 1191 16 | remote es1.isponeder.com 1191 17 | remote es2.isponeder.com 1191 18 | remote fr1.isponeder.com 1191 19 | remote fr2.isponeder.com 1191 20 | remote fr3.isponeder.com 1191 21 | remote hk1.isponeder.com 1191 22 | remote id1.isponeder.com 1191 23 | remote ie1.isponeder.com 1191 24 | remote in1.isponeder.com 1191 25 | remote mx1.isponeder.com 1191 26 | remote nl1.isponeder.com 1191 27 | remote nl2.isponeder.com 1191 28 | remote nz1.isponeder.com 1191 29 | remote se1.isponeder.com 1191 30 | remote se3.isponeder.com 1191 31 | remote tcp-at2.isponeder.com 443 32 | remote tcp-au2.isponeder.com 443 33 | remote tcp-be1.isponeder.com 443 34 | remote tcp-be2.isponeder.com 443 35 | remote tcp-ca1.isponeder.com 443 36 | remote tcp-ca2.isponeder.com 443 37 | remote tcp-ch1.isponeder.com 443 38 | remote tcp-de1.isponeder.com 443 39 | remote tcp-de2.isponeder.com 443 40 | remote tcp-de3.isponeder.com 443 41 | remote tcp-de4.isponeder.com 443 42 | remote tcp-de5.isponeder.com 443 43 | remote tcp-de6.isponeder.com 443 44 | remote tcp-dk3.isponeder.com 443 45 | remote tcp-es1.isponeder.com 443 46 | remote tcp-es2.isponeder.com 443 47 | remote tcp-fr1.isponeder.com 443 48 | remote tcp-fr2.isponeder.com 443 49 | remote tcp-fr3.isponeder.com 443 50 | remote tcp-hk1.isponeder.com 443 51 | remote tcp-id1.isponeder.com 443 52 | remote tcp-ie1.isponeder.com 443 53 | remote tcp-in1.isponeder.com 443 54 | remote tcp-mx1.isponeder.com 443 55 | remote tcp-nl1.isponeder.com 443 56 | remote tcp-nl2.isponeder.com 443 57 | remote tcp-nz1.isponeder.com 443 58 | remote tcp-se1.isponeder.com 443 59 | remote tcp-se3.isponeder.com 443 60 | remote tcp-uk1.isponeder.com 443 61 | remote tcp-uk2.isponeder.com 443 62 | remote tcp-uk3.isponeder.com 443 63 | remote tcp-uk4.isponeder.com 443 64 | remote tcp-uk5.isponeder.com 443 65 | remote tcp-uk6.isponeder.com 443 66 | remote tcp-uk7.isponeder.com 443 67 | remote tcp-za1.isponeder.com 443 68 | remote udp-au3.isponeder.com 443 69 | remote uk1.isponeder.com 1191 70 | remote uk2.isponeder.com 1191 71 | remote uk3.isponeder.com 1191 72 | remote uk4.isponeder.com 1191 73 | remote uk5.isponeder.com 1191 74 | remote uk6.isponeder.com 1191 75 | remote uk7.isponeder.com 1191 76 | remote za1.isponeder.com 1191 77 | -------------------------------------------------------------------------------- /security/vpnsecure/us_servers.txt: -------------------------------------------------------------------------------- 1 | remote tcp-us1.isponeder.com 443 2 | remote tcp-us10.isponeder.com 443 3 | remote tcp-us11.isponeder.com 443 4 | remote tcp-us12.isponeder.com 443 5 | remote tcp-us13.isponeder.com 443 6 | remote tcp-us14.isponeder.com 443 7 | remote tcp-us15.isponeder.com 443 8 | remote tcp-us16.isponeder.com 443 9 | remote tcp-us2.isponeder.com 443 10 | remote tcp-us4.isponeder.com 443 11 | remote tcp-us5.isponeder.com 443 12 | remote tcp-us6.isponeder.com 443 13 | remote tcp-us7.isponeder.com 443 14 | remote tcp-us8.isponeder.com 443 15 | remote tcp-us9.isponeder.com 443 16 | remote udp-ustream1.isponeder.com 443 17 | remote us1.isponeder.com 1191 18 | remote us10.isponeder.com 1191 19 | remote us11.isponeder.com 1191 20 | remote us12.isponeder.com 1191 21 | remote us13.isponeder.com 1191 22 | remote us14.isponeder.com 1191 23 | remote us15.isponeder.com 1191 24 | remote us16.isponeder.com 1191 25 | remote us2.isponeder.com 1191 26 | remote us4.isponeder.com 1191 27 | remote us5.isponeder.com 1191 28 | remote us6.isponeder.com 1191 29 | remote us7.isponeder.com 1191 30 | remote us8.isponeder.com 1191 31 | remote us9.isponeder.com 1191 32 | remote us9.isponeder.com 1191 33 | remote ustream1.isponeder.com 1191 34 | -------------------------------------------------------------------------------- /ssl/create_dkim_key.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # simple script to create dkim key for postfix 4 | # 5 | # Author: Arul Selvan 6 | # Version: Mar 16, 2014 7 | 8 | # create the keys for the dkim setup 9 | strength=1024 10 | 11 | if [ $# -gt 0 ]; then 12 | strength=$1 13 | fi 14 | 15 | #how to create PEM keys 16 | openssl genrsa -out private.key $strength 17 | openssl rsa -in private.key -out public.key -pubout -outform PEM 18 | 19 | # now copy it to right filename specified in postfix configs, in this 20 | # example it is mail.* 21 | cp private.key /etc/mail/mail.private.key 22 | -------------------------------------------------------------------------------- /ssl/rootCA_howto.txt: -------------------------------------------------------------------------------- 1 | # 2 | # How to create a root CA to be used to sign SSL certificates. 3 | # 4 | # Author: Arul Selvan 5 | # Version: Nov 3, 2015 6 | # 7 | # Steps: 8 | # * create a CA cert 9 | # * import and trust that on all clients 10 | # * create ssl key, CSR for the SSL 11 | # * create a EXT text file 12 | # * create a signed cert w/ the CSR 13 | # * install to webserver, device, router etc 14 | # * for Asus3200 router follow the steps 15 | # * Login to admin UI 16 | # * Go to WAN 17 | # * Go to DDNS 18 | # * Select www.asus.com 19 | # * add selvans to hostname 20 | # * select Import your own cert and use server.key,server.crt 21 | # * Apply 22 | # * Once loaded in browser, make sure you trust the cert. 23 | # 24 | 25 | # 26 | # The code below shows the example of how to create a rootCA and a SSL cert to 27 | # be used by Asus3200 router. 28 | # 29 | 30 | # create a CA private key 31 | openssl genrsa -out asus_routerCA.key 2048 32 | 33 | # generate root cert (using private key above) 34 | openssl req -x509 -new -nodes -key asus_routerCA.key -sha256 -days 5000 -out asus_routerCA.pem 35 | 36 | # import the asus_routerCA.pem into OS CA store (in MacOS, its keychain) and trust this CA "Trust Always" 37 | 38 | # create a private key for SSL cert for each SSL service 39 | openssl genrsa -out selvans.asuscomm.com.key 2048 40 | 41 | # create a CSR for signing w/ our CA cert asus_routerCA.pem 42 | openssl req -new -key selvans.asuscomm.com.key -out selvans.asuscomm.com.csr 43 | 44 | # create a EXT config file for SAN (Subject Alternative Name) 45 | cat << EOF > selvans.asuscomm.com.ext 46 | authorityKeyIdentifier=keyid,issuer 47 | basicConstraints=CA:FALSE 48 | keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment 49 | subjectAltName = @alt_names 50 | 51 | [alt_names] 52 | DNS.1 = selvans.asuscomm.com 53 | EOL 54 | 55 | # finally sign the cert 56 | openssl x509 -req -in selvans.asuscomm.com.csr -CA asus_routerCA.pem -CAkey asus_routerCA.key -CAcreateserial -out selvans.asuscomm.com.crt -days 5000 -sha256 -extfile selvans.asuscomm.com.ext 57 | 58 | # all done 59 | -------------------------------------------------------------------------------- /tools/LdapAuthenticator.php: -------------------------------------------------------------------------------- 1 | handle = ldap_connect($this->AD_SERVER); 17 | if ( ! $this->handle ) { 18 | // can't connect 19 | die("ERROR: unable to connect to $AD_SERVER; handle=$this->handle \n"); 20 | } 21 | ldap_set_option($this->handle, LDAP_OPT_PROTOCOL_VERSION, 3); // Recommended for AD 22 | } 23 | 24 | public function authenticate($user, $password) { 25 | if ( ! $user || ! $password ) { 26 | die("user or password empty!, try with valid user/password\n"); 27 | return; 28 | } 29 | try { 30 | $status = ldap_bind($this->handle, $user, $password); 31 | if ( ! $status) { 32 | die("Authentication failed!\n"); 33 | } 34 | else { 35 | die("Authentication Success!\n"); 36 | } 37 | } 38 | catch (Exception $e) { 39 | die ("Authenticaion failed: ". $e->getMessage() . "\n"); 40 | } 41 | } 42 | } 43 | 44 | $lda = new LdapAuthenticator(); 45 | $lda->authenticate("user", "password"); 46 | 47 | ?> 48 | -------------------------------------------------------------------------------- /tools/ScanQRCode.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | qr_image = $image; 31 | 32 | # validate file exist & is the right type 33 | if (! file_exists($this->qr_image)) { 34 | throw new Exception ("file '" . $this->qr_image . "' does not exists!"); 35 | } 36 | 37 | $mimeType = mime_content_type($this->qr_image); 38 | 39 | if (! in_array($mimeType, $this->validFiles)) { 40 | throw new Exception("image file mimeType: " . $mimeType . " is not valid!"); 41 | } 42 | } 43 | 44 | public function scan() { 45 | $output=null; 46 | $rc=null; 47 | 48 | exec("zbarimg -q ". $this->qr_image, $output, $rc); 49 | if ( $rc != 0 ) { 50 | throw new Exception("zbarimage scan failed for '". $this->qr_image . "' error code='" . $rc); 51 | } 52 | return implode(" ",$output); 53 | } 54 | } 55 | 56 | # --------- Main --------------- 57 | 58 | try { 59 | $qr_code = new ScanQRCode($argv[1]); 60 | echo $qr_code->scan(), "\n"; 61 | } 62 | catch (Exception $e) { 63 | echo "ERROR: " .$e->getMessage() . "\n"; 64 | } 65 | 66 | ?> 67 | -------------------------------------------------------------------------------- /tools/ad2unix_time.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # ad2unix_time.sh --- convert AD time to Unix human readble time 4 | # 5 | # Author: Arul Selvan 6 | # Version: Sep 25, 2021 7 | # 8 | 9 | my_name=`basename $0` 10 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 11 | 12 | # commandline arguments 13 | options_list="t:h" 14 | ad_timestamp="" 15 | 16 | usage() { 17 | echo "Usage: $my_name -t " 18 | exit 0 19 | } 20 | 21 | # process commandline 22 | while getopts "$options_list" opt; do 23 | case $opt in 24 | t) 25 | ad_timestamp=$OPTARG 26 | ;; 27 | h) 28 | usage 29 | ;; 30 | \?) 31 | usage 32 | ;; 33 | :) 34 | usage 35 | ;; 36 | esac 37 | done 38 | 39 | if [ -z $ad_timestamp ] ; then 40 | usage 41 | fi 42 | echo "[INFO] converting AD timestamp $ad_timestamp to human readable date ... " >$log_file 43 | 44 | # convert unix seconds 45 | time_secs=$(echo "($ad_timestamp/10000000)-11644473600" | /usr/bin/bc) 46 | 47 | # construct date it expires 48 | readable_date=$(date -r $time_secs) 49 | 50 | # subtract expiry_time_sec from today_sec and convert to calculate 51 | # number of days left for password expiry 52 | today_sec=$(/bin/date +%s) 53 | num_days=$(echo "($time_secs - $today_sec)/60/60/24" | /usr/bin/bc) 54 | 55 | echo "The timestamp represents '$readable_date' which is $num_days days from today" | tee -a $log_file 56 | -------------------------------------------------------------------------------- /tools/add_ssh_pubkey.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # add_ssh_pubkey.sh - script to append the public key to authorized_keys for keybased login 4 | # 5 | # note: ssh-copy-id does the same thing but it doesn't consistenly work on all systems. 6 | # 7 | # Author: Arul Selvan 8 | # Version: Dec 8, 2014 9 | # 10 | user="" 11 | host="" 12 | my_pub_key=`cat ~/.ssh/id_rsa.pub` 13 | 14 | while getopts ":u:h:" opt; do 15 | case $opt in 16 | u) 17 | user=$OPTARG 18 | ;; 19 | h) 20 | host=$OPTARG 21 | ;; 22 | esac 23 | done 24 | 25 | if [ -z $user ] || [ -z $host ] ; then 26 | echo "Usage: $0 -h -u " 27 | exit 28 | fi 29 | 30 | echo "[INFO] Adding key to remote host: $user@$host ..." 31 | remote_command="echo \"$my_pub_key\" >> .ssh/authorized_keys" 32 | ssh $user@$host $remote_command 33 | -------------------------------------------------------------------------------- /tools/apache_version_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # apache_version_check.sh --- quick and dirty script to check apache version. 4 | # 5 | # Author: Arul Selvan 6 | # version: Oct 6, 2021 7 | # 8 | 9 | my_name=`basename $0` 10 | run_logfile="/tmp/$(echo $my_name|cut -d. -f1).log" 11 | options_list="p:s:h" 12 | 13 | # fill in your desired IP/host and port where apache might be running. 14 | servers="192.168.1.1,192.168.1.2,192.168.1.3, trex " 15 | ports="80,443,8080" 16 | 17 | usage() { 18 | echo "Usage: $my_name [options]" 19 | echo " -s --- comma separated list of hostname or IPs [defaut: $servers]" 20 | echo " -p --- comma separated list of ports [default: $ports]" 21 | exit 0 22 | } 23 | 24 | # ------ main ------------- 25 | # process commandline 26 | while getopts "$options_list" opt; do 27 | case $opt in 28 | s) 29 | servers=$OPTARG 30 | ;; 31 | p) 32 | ports=$OPTARG 33 | ;; 34 | h) 35 | usage 36 | ;; 37 | \?) 38 | usage 39 | ;; 40 | :) 41 | usage 42 | ;; 43 | esac 44 | done 45 | 46 | ts=$(date +"%D %H:%M %p") 47 | echo "[INFO] $my_name starting at [$ts] ... " |/usr/bin/tee $run_logfile 48 | 49 | IFS="," 50 | for s in $servers ; do 51 | s=`echo $s|tr -d ' '` 52 | echo "Checking server: $s" | tee -a $run_logfile 53 | for p in $ports ; do 54 | p=`echo $p|tr -d ' '` 55 | v=`curl -m2 -vs $s:$p 2>&1|awk '/Server:/ {print $3;}'` 56 | if [ -z $v ]; then 57 | v="N/A" 58 | fi 59 | echo -e "\tPort:Version: $p:$v" | tee -a $run_logfile 60 | done 61 | done 62 | 63 | -------------------------------------------------------------------------------- /tools/audio2video.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # audio2video.sh --- stupid simple wrapper to convert audion to video w/ static image 4 | # 5 | # NOTE: need ffmpeg binary in the path 6 | # 7 | # Author : Arul Selvan 8 | # Version: Man 4, 2023 9 | 10 | my_name=`basename $0` 11 | os_name=`uname -s` 12 | options="p:i:h?" 13 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 14 | PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" 15 | 16 | source_path="" 17 | cover_image="" 18 | dest_path="" 19 | 20 | usage() { 21 | echo "" 22 | echo "Usage: $my_name -p -i " 23 | echo " -p file/path for single file (or quoted for wildcard) convert audio to video" 24 | echo " -i cover/static png image to use for all video files" 25 | echo "" 26 | echo "example: $my_name -i cover.png -p \"$HOME/*.m4a\"" 27 | echo "" 28 | exit 0 29 | } 30 | 31 | # ---------- main -------------- 32 | # parse commandline options 33 | while getopts $options opt; do 34 | case $opt in 35 | p) 36 | source_path="$OPTARG" 37 | ;; 38 | i) 39 | cover_image="$OPTARG" 40 | ;; 41 | ?) 42 | usage 43 | ;; 44 | h) 45 | usage 46 | ;; 47 | *) 48 | usage 49 | ;; 50 | esac 51 | done 52 | 53 | if [ -f $log_file ] ; then 54 | rm $log_file 55 | fi 56 | 57 | if [ -z "$source_path" ] ; then 58 | usage 59 | fi 60 | 61 | if [ -z "$cover_image" ] ; then 62 | usage 63 | fi 64 | 65 | echo "[INFO] $my_name starting ..." > $log_file 66 | 67 | # check if source path is a single file 68 | if [ -f "$source_path" ] ; then 69 | file_list="$source_path" 70 | else 71 | dir_name=$(dirname "$source_path") 72 | file_name=$(basename "$source_path") 73 | file_list=`ls -1 $dir_name/$file_name` 74 | fi 75 | 76 | for fname in ${file_list} ; do 77 | # if filename is directory, skip 78 | if [ -d $fname ] ; then 79 | echo "[WARN] $fname is a directory, skipping ..." | tee -a $log_file 80 | continue 81 | fi 82 | base_part=${fname##*/} 83 | name_part=${base_part%.*} 84 | 85 | echo "converting $fname to ${name_part}.mp4 ..." 86 | ffmpeg -i $fname -i $cover_image -filter_complex "loop=-1:1:0" -shortest videos/${name_part}.mp4 87 | 88 | done 89 | -------------------------------------------------------------------------------- /tools/create_videos.csv: -------------------------------------------------------------------------------- 1 | Directory Path, Image Files, Background MP3, Video Title, Output File Name, Create Date 2 | /var/www/photos/morocco-egypt_sep2023, .jpg|.JPG, /data/videos4youtube/mp3/background.mp3, "Morocco & Egypt Vacation\nSep 2-17, 2023", morocco-egypt_sep2023.mp4, 202309020101 3 | /var/www/photos/year-2023, .jpg|.JPG, /data/videos4youtube/mp3/Feel-Good.mp3, "Highlights of 2023\nAll pictures from the year 2023", year-2023.mp4, 202312310101 4 | -------------------------------------------------------------------------------- /tools/curl_ws_run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Quick wrapper shell script for running a webservice call with client certfificate 4 | # 5 | # Author: Arul Selvan 6 | # Version: Feb 14, 2013 7 | # 8 | # NOTES: the private key is extracted from mycert.pfx using following command and 'password' 9 | # as password 10 | # openssl pkcs12 -in mycert.pfx -out mycert.pem -clcerts 11 | # 12 | options_list="r:s:o:" 13 | curl_cmd=/usr/bin/curl 14 | request_file=soap_request.txt 15 | output_file=soap_response.out 16 | certificate="mycert.pem" 17 | curl_args='-k -s --cert $certificate:password --key $certificate -H "Content-Type: text/xml; charset=utf-8" -H "SOAPAction:"' 18 | service="https://host/soapEndpoint" 19 | 20 | usage() { 21 | echo "Usage: $0 [-r | -o | -s ]" 22 | exit 1 23 | } 24 | 25 | while getopts "$options_list" opt; do 26 | case $opt in 27 | r) 28 | request_file=$OPTARG 29 | ;; 30 | s) 31 | service=$OPTARG 32 | ;; 33 | o) 34 | output_file=$OPTARG 35 | ;; 36 | \?) 37 | echo "Invalid option: -$OPTARG" 38 | usage 39 | ;; 40 | :) 41 | echo "Option -$OPTARG requires and argument." 42 | usage 43 | ;; 44 | esac 45 | done 46 | 47 | echo "Service: $service" 48 | echo "Request: $request_file" 49 | echo "Output: $output_file" 50 | 51 | $curl_cmd $curl_args -d @$request_file -X POST $service >$output_file 2>&1 52 | -------------------------------------------------------------------------------- /tools/dedup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # dedup.sh --- identifiy and separate files w/ same content but different name 4 | # 5 | # 6 | # Author: Arul Selvan 7 | # Version: Feb 6, 2021 8 | # 9 | 10 | export PATH="/usr/bin:/sbin:/usr/local/bin:$PATH" 11 | os_name=`uname -s` 12 | my_name=`basename $0` 13 | run_date=`date +'%F-%H%M'` 14 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 15 | options_list="f:s:d:h" 16 | 17 | source_dir="" 18 | dest_dir="" 19 | file_filter="*" 20 | mdsum_file=/tmp/${my_name}_mdsums.txt 21 | 22 | usage() { 23 | echo "Usage: $my_name [options]" 24 | echo " -s --- source path where duplicate files are found" 25 | echo " -d --- destination path to move unique files from source" 26 | echo " -f --- filter ex: \"*.jpg *.pdf\" [default: *]" 27 | exit 0 28 | } 29 | 30 | # process commandline 31 | while getopts "$options_list" opt; do 32 | case $opt in 33 | s) 34 | source_dir=$OPTARG 35 | ;; 36 | d) 37 | dest_dir=$OPTARG 38 | ;; 39 | f) 40 | file_filter="$OPTARG" 41 | ;; 42 | h) 43 | usage 44 | ;; 45 | \?) 46 | usage 47 | ;; 48 | :) 49 | usage 50 | ;; 51 | esac 52 | done 53 | 54 | # no source or dest? 55 | if [[ -z $source_dir || -z $dest_dir ]] ; then 56 | echo "[ERROR] missing source or dest args!" 57 | usage 58 | fi 59 | 60 | echo "[INFO] starting '$my_name $@'" | tee $log_file 61 | file_list=`(cd $source_dir; ls -1 $file_filter)` 62 | total=`echo $file_list|wc -w|tr -d ' '` 63 | 64 | rm -f $mdsum_file 65 | count=1 66 | for fname in $file_list ; do 67 | printf "[INFO] creating md5sum file $count/$total ...\r" 68 | (cd $source_dir; md5sum $fname >> $mdsum_file) 69 | ((count++)) 70 | done 71 | echo 72 | unique_file_list=`cat $mdsum_file|sort -u -k1,1|awk '{print $2}'` 73 | 74 | for fname in $unique_file_list ; do 75 | printf "[INFO] copying ${source_dir}/${fname} to ${dest_dir} ...\r" 76 | echo "[INFO] copying ${source_dir}/${fname} to ${dest_dir} " >> $log_file 77 | cp ${source_dir}/${fname} ${dest_dir}/. 78 | done 79 | echo 80 | -------------------------------------------------------------------------------- /tools/elapsed_duration.php: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/php 2 | 3 | format('Y-m-d'); 19 | $start_date = new DateTime($start_date_string); 20 | printf ("%s\n","Difference between $start_date_string and now ($cur_date_string) is ... "); 21 | $interval = $start_date->diff($cur_date); 22 | printf ("Total Days: %s\n", $interval->format('%a')); 23 | printf ("Total YMDHMS: %s\n",$interval->format('%y yrs, %m months, %d days, %h hours, %i minutes, %s seconds')); 24 | 25 | -------------------------------------------------------------------------------- /tools/fat32_size.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # fat32_size.sh --- script to split (and combine later) files for fat32 fs. 5 | # 6 | # Author: Arul Selvan 7 | # Version: Sep 21, 2014 8 | 9 | # 4gb (note ths '*' need to be escaped!) 10 | four_gb=`expr 4 \* 1024 \* 1024 \* 1024` 11 | split_args="--bytes=1GB --numeric-suffixes=1" 12 | md5sum_command="md5sum -b" 13 | 14 | usage() { 15 | echo "Usage: $0 --split |--combine " 16 | exit 17 | } 18 | 19 | split_file() { 20 | fname=$1 21 | if [ -z $fname ]; then 22 | usage 23 | fi 24 | 25 | # calculate file size to see if we need to split 26 | #fsize=`ls -l $fname |cut -d' ' -f5` 27 | fsize=`ls -l $fname |awk '{print $5;}'` 28 | if [ $fsize -gt $four_gb ]; then 29 | echo "File: $fname is too big for fat32, needs spliting..." 30 | else 31 | echo "INFO: File $fname already is under 4GB, no need to split for fat32" 32 | exit 33 | fi 34 | 35 | # calculate md5sum 36 | echo "Calculating md5sum for $fname... (may take long time)" 37 | $md5sum_command $fname > $fname.md5 38 | 39 | # 40 | # split using zip with 1GB chunks each 41 | echo "Spliting $fname into 1GB chunks ... (may take long time)" 42 | split $split_args $fname $fname.part 43 | echo "Done spliting." 44 | exit 45 | } 46 | 47 | combine_file() { 48 | fname=$1 49 | if [ -z $fname ]; then 50 | usage 51 | fi 52 | 53 | # we expect $fname.part01...0n 54 | echo "Combining the files split earlier to full size...(may take long time)..." 55 | cat $fname.part* > $fname 56 | 57 | # check the md5sum (we expect the $fname.md5 created earlier) 58 | echo "Verifying file integrity after combining... (may take a long time) ..." 59 | if [ $os = "Darwin" ]; then 60 | $md5sum_command $fname >$fname.md5.combined 61 | diff $fname.md5 $fname.md5.combined >/dev/null 2>&1 62 | else 63 | md5sum -c $fname.md5 64 | fi 65 | if [ $? -ne 0 ]; then 66 | echo "ERROR: md5sum does not match after combining, file parts may be corrupted!" 67 | else 68 | echo "Successfully combined $fname using $fname.part" 69 | fi 70 | exit 71 | } 72 | 73 | # -------- main ----------- 74 | # check the os, MacOS does not have md5sum and split works in different way 75 | os=`uname -s` 76 | if [ $os = "Darwin" ]; then 77 | split_args="-a3 -b1024m" 78 | md5sum_command="md5 -q" 79 | fi 80 | 81 | # parse commandline 82 | while [ "$1" ] 83 | do 84 | if [ "$1" = "--split" ]; then 85 | shift 1 86 | split_file $1 87 | break 88 | elif [ "$1" = "--combine" ]; then 89 | shift 1 90 | combine_file $1 91 | break 92 | else 93 | usage 94 | fi 95 | done 96 | 97 | # we get here if there are no args 98 | usage 99 | -------------------------------------------------------------------------------- /tools/git_migrate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 4 | # git_migrate.sh --- simple script to migrate/copy repo from one location to another. 5 | # 6 | # This script copies a git repo from one location to other including branch, tags history etc. 7 | # Note: make sure you create an empty GIT repo at the dstination location first. 8 | # 9 | # Author: Arul Selvan 10 | # Version: Feb 21, 2022 11 | # 12 | 13 | my_name=`basename $0` 14 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 15 | src_url="" 16 | dst_url="" 17 | repo_name="" 18 | tmp_dir="/tmp" 19 | 20 | # commandline options 21 | options="s:d:r:t:h" 22 | 23 | # print usage 24 | function usage() { 25 | cat < -d -r 28 | 29 | -s repo url of the src location 30 | -d repo url of the dst location [note: repo must exist/created] 31 | -r name of a repository to copy from src to dst 32 | -t name of a temporary directory to use [default: $tmp_dir] 33 | 34 | Examples: 35 | $my_name -s https://github.com/src-location -d https://github.com/dst-location -r myrepo.git 36 | 37 | EOF 38 | exit 39 | } 40 | 41 | # ----------- main entry ----------- 42 | echo "[INFO] starting ..." | tee $log_file 43 | 44 | # commandline parse 45 | while getopts $options opt; do 46 | case $opt in 47 | s) 48 | src_url=$OPTARG 49 | ;; 50 | d) 51 | dst_url=$OPTARG 52 | ;; 53 | r) 54 | repo_name=$OPTARG 55 | ;; 56 | t) 57 | tmp_dir=$OPTARG 58 | ;; 59 | ?) 60 | usage 61 | ;; 62 | h) 63 | usage 64 | ;; 65 | esac 66 | done 67 | 68 | if [ -z $src_url ] || [ -z $dst_url ] || [ -z $repo_name ] ; then 69 | echo "[ERROR] missing one or more required arguments! See usage below" | tee -a $log_file 70 | usage 71 | fi 72 | 73 | echo "[INFO] migrate '$src_url/$repo_name' to '$dst_url/$repo_name' ..." | tee -a $log_file 74 | 75 | git clone --bare $src_url/$repo_name $tmp_dir/$repo_name 2>&1 | tee -a $log_file 76 | cd $tmp_dir/$repo_name 77 | git push --mirror $dst_url/$repo_name 2>&1 | tee -a $log_file 78 | 79 | echo "[INFO] repos migrated." | tee -a $log_file 80 | -------------------------------------------------------------------------------- /tools/gps_echo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # gps_echo.py 4 | # Simple script to read gps from gps device connected to serial port. The output 5 | # is meant for constructing a google map location URL based on the lat/lon data 6 | # read as shown below. 7 | # 8 | # https://www.google.com/maps?q=`python gps_echo.py`" 9 | # 10 | # Author: Arul Selvan 11 | # Version: Sep 4, 2022 12 | # 13 | # Prereq: 14 | # apt-get install python-serial python-nmea2 15 | # 16 | import serial 17 | import time 18 | import string 19 | import pynmea2 20 | 21 | # serial port where GPS device is connected 22 | port="/dev/ttyAMA0" 23 | s=serial.Serial(port, baudrate=9600, timeout=0.5) 24 | dataout = pynmea2.NMEAStreamReader() 25 | 26 | while True: 27 | if s.in_waiting: 28 | try: 29 | line=s.readline() 30 | except: 31 | print("ERROR: failed reading gps serial device at: "+ port) 32 | quit() 33 | 34 | if line[0:6] == "$GPRMC": 35 | msg=pynmea2.parse(line) 36 | lat=msg.latitude 37 | lon=msg.longitude 38 | gps = str(lat) + "," + str(lon) 39 | print(gps) 40 | exit() 41 | 42 | -------------------------------------------------------------------------------- /tools/http_cap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # simple tcpdump script to capture http data on specified network or host (not host) with 4 | # a specific payload_size (OS: macOS or Linux) 5 | # 6 | # Author: Arul Selvan 7 | # Version: May 24, 2015 8 | 9 | # adjust these to your host and network 10 | my_if="eth0" 11 | my_net="192.168.0.0/16" 12 | cap_file="/tmp/http_cap.tcpdump" 13 | payload_size=32 14 | 15 | if [ `uname -s` = "Darwin" ] ; then 16 | my_host=`ipconfig getifaddr $my_if` 17 | else 18 | my_host=`hostname -i` 19 | fi 20 | 21 | if [ -z $my_host ] ; then 22 | echo "[ERROR] The interface '$my_if' is either not up or don't have IP assigned!" 23 | exit 24 | fi 25 | 26 | # what to capture (all hosts or everything but my host) 27 | if [ ! -z $1 ] && [ $1 = "-a" ] ; then 28 | include="net $my_net" 29 | else 30 | include="host not $my_host" 31 | fi 32 | 33 | filter="$include and port http and tcp and greater $payload_size" 34 | # uncoment to filter just post data, i.e. P=0x50 O=0x4f S=0x53 T=0x54 35 | #filter="$include and port http and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354" 36 | 37 | # capture it 38 | sudo tcpdump -vvv -s0 -i $my_if -A -w $cap_file $filter 39 | -------------------------------------------------------------------------------- /tools/human_time.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # human_time.sh.sh --- script to convert UNIX seconds,mseconds to date/time stamp 4 | # 5 | # 6 | # Author: Arul Selvan 7 | # Created: Dec 19, 2023 8 | # 9 | 10 | # version format YY.MM.DD 11 | version=23.12.19 12 | my_name="`basename $0`" 13 | my_version="`basename $0` v$version" 14 | my_title="Script to convert UNIX seconds,mseconds to date/time stamp" 15 | my_dirname=`dirname $0` 16 | my_path=$(cd $my_dirname; pwd -P) 17 | my_logfile="/tmp/$(echo $my_name|cut -d. -f1).log" 18 | default_scripts_github=$HOME/src/scripts.github 19 | scripts_github=${SCRIPTS_GITHUB:-$default_scripts_github} 20 | 21 | # commandline options 22 | options="s:m:nvh?" 23 | 24 | # ensure path for cron runs 25 | export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" 26 | 27 | mseconds="" 28 | seconds="" 29 | from_now="0" 30 | 31 | usage() { 32 | cat << EOF 33 | $my_name - $my_title 34 | 35 | Usage: $my_name [options] 36 | -s ---> seconds to convert to date/timestamp 37 | -m ---> milli seconds to convert to date/timestamp 38 | -n ---> means "now" i.e. -s -m arguments assumed to be offset from now 39 | -v ---> enable verbose, otherwise just errors are printed 40 | -h ---> print usage/help 41 | 42 | example: $my_name -s \`date +%s\` # prints time now in readable format 43 | example: $my_name -n -s 42044 # the datetime will be 42044 seconds from now 44 | 45 | EOF 46 | exit 0 47 | } 48 | 49 | 50 | # ------------------------------- main ------------------------------- 51 | # First, make sure scripts root path is set, we need it to include files 52 | if [ ! -z "$scripts_github" ] && [ -d $scripts_github ] ; then 53 | # include logger, functions etc as needed 54 | source $scripts_github/utils/logger.sh 55 | source $scripts_github/utils/functions.sh 56 | else 57 | echo "ERROR: SCRIPTS_GITHUB env variable is either not set or has invalid path!" 58 | echo "The env variable should point to root dir of scripts i.e. $default_scripts_github" 59 | exit 1 60 | fi 61 | # init logs 62 | log.init $my_logfile 63 | 64 | # parse commandline options 65 | while getopts $options opt ; do 66 | case $opt in 67 | n) 68 | from_now=1 69 | ;; 70 | s) 71 | seconds="$OPTARG" 72 | ;; 73 | m) 74 | mseconds="$OPTARG" 75 | ;; 76 | v) 77 | verbose=1 78 | ;; 79 | e) 80 | email_address="$OPTARG" 81 | ;; 82 | ?|h|*) 83 | usage 84 | ;; 85 | esac 86 | done 87 | 88 | 89 | # validate args 90 | if [ -z $seconds ] && [ -z $mseconds ] ; then 91 | log.error "Required argument is missing, see usage" 92 | usage 93 | fi 94 | 95 | if [ ! -z $seconds ] ; then 96 | log.stat "Timestamp $seconds (secs) translate to: $(convert_seconds $seconds $from_now)" 97 | else 98 | log.stat "Timestamp $mseconds (msec) translate to: $(convert_mseconds $mseconds $from_now)" 99 | fi 100 | -------------------------------------------------------------------------------- /tools/lottery_number.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # lottery_number.sh 4 | # This script generates lottery number using /dev/random assuming the OS 5 | # entropy is reasonably high for true random number. In recent Linux kernel 6 | # the system entropy at /proc/sys/kernel/random/entropy_avail is hardcoded 7 | # to 256. I don't know or understand why but as per documentaion the poolsize 8 | # is set to be 256 as well i.e. cat /proc/sys/kernel/random/poolsize 9 | # 10 | # Author: Arul Selvan 11 | # Created: Jul 27, 2022 12 | # 13 | 14 | # version format YY.MM.DD 15 | version=23.07.27 16 | my_name="`basename $0`" 17 | my_version="`basename $0` v$version" 18 | 19 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 20 | options="r:i:m:vh?" 21 | white_range=1-70 22 | mega_range=1-25 23 | iterations=512 24 | total_numbers=5 25 | random_device="/dev/random" 26 | 27 | # ensure path for cron runs 28 | export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" 29 | 30 | usage() { 31 | cat << EOF 32 | 33 | Usage: $my_name [options] 34 | -r ---> Range for main numbers i.e. white balls [default: $white_range] 35 | -m ---> Range for mega ball [default: $mega_range] 36 | -i ---> iterate in loop to create new entropy [default: $iterations] 37 | -h ---> print usage/help 38 | 39 | example: $my_name -h 40 | 41 | EOF 42 | exit 0 43 | } 44 | 45 | iterate_loop() { 46 | echo "Running iteration of $iterations ..." 47 | for (( i=0; i<$iterations; i++ )) ; do 48 | shuf --random-source=$random_device -n$total_numbers -i$white_range 2>&1 >/dev/null 49 | done 50 | } 51 | 52 | 53 | # ---------- main -------------- 54 | echo $my_version | tee $log_file 55 | # parse commandline options 56 | while getopts $options opt ; do 57 | case $opt in 58 | i) 59 | iterations="$OPTARG" 60 | ;; 61 | r) 62 | white_range="$OPTARG" 63 | ;; 64 | m) 65 | mega_range="$OPTARG" 66 | ;; 67 | ?|h|*) 68 | usage 69 | ;; 70 | esac 71 | done 72 | 73 | iterate_loop 74 | 75 | # get whiteball numbers 76 | white_numbers=`shuf --random-source=$random_device -n$total_numbers -i$white_range|tr '\n' ' '` 77 | 78 | # get megaball numbers 79 | megaball_number=`shuf --random-source=$random_device -n1 -i$mega_range |tr '\n' ' '` 80 | 81 | echo "Your lucky lotto number is: $white_numbers [ $megaball_number]" |tee -a $log_file 82 | -------------------------------------------------------------------------------- /tools/media_type.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # media_type.sh --- list file media type, optionally filter to show specific type 4 | # 5 | # Given a path, recursivly list filename and type of the entry is one of those "media" 6 | # types like jpg|jpeg|JPEG|JPG|PDF|pdf ... etc 7 | # 8 | # Author : Arul Selvan 9 | # Version : Mar 5, 2023 --- original version 10 | # 11 | 12 | # ensure path for cron runs 13 | export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" 14 | 15 | # version format YY.MM.DD 16 | version=23.03.05 17 | my_name=`basename $0` 18 | my_version="$my_name v$version" 19 | os_name=`uname -s` 20 | options="p:t:h" 21 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 22 | source_path="" 23 | type_filter="" 24 | 25 | usage() { 26 | echo "" 27 | echo "Usage: $my_name [options]" 28 | echo " -p ---> path to start to recurse from" 29 | echo " -t ---> filter by type i.e. mp4, mp4, m2a etc" 30 | echo "" 31 | echo "example: $my_name -p \"/home/music\" -t mp3" 32 | echo "" 33 | exit 0 34 | } 35 | 36 | # check if file is a media file that could support metadata 37 | is_media() { 38 | local f=$1 39 | local mtype=`file -b --mime-type $f | cut -d '/' -f 2` 40 | 41 | case $mtype in 42 | jpg|jpeg|JPEG|JPG|PDF|pdf|mpeg|MPEG|MP3|mp3|m4a|x-m4a|mp4|MP4|png|PNG|mov|MOV|gif|GIF|TIFF|tiff) 43 | # see if we need to filter 44 | if [ ! -z $type_filter ] ; then 45 | if [ $mtype = $type_filter ] ; then 46 | echo "File: $f ; type: $mtype" 47 | fi 48 | else 49 | echo "File: $f ; type: $mtype" 50 | fi 51 | ;; 52 | esac 53 | } 54 | 55 | # ---------- main -------------- 56 | # parse commandline options 57 | while getopts $options opt; do 58 | case $opt in 59 | p) 60 | source_path="$OPTARG" 61 | ;; 62 | t) 63 | type_filter="$OPTARG" 64 | ;; 65 | h) 66 | usage 67 | ;; 68 | *) 69 | usage 70 | ;; 71 | esac 72 | done 73 | 74 | 75 | if [ -f $log_file ] ; then 76 | rm $log_file 77 | fi 78 | echo "[INFO] $my_version" | tee -a $log_file 79 | 80 | if [ -z "$source_path" ] ; then 81 | echo "[ERROR] required arguments missing i.e. path " | tee -a $log_file 82 | usage 83 | fi 84 | 85 | # just use find 86 | find $source_path -type f | while read file; do is_media $file; done 87 | -------------------------------------------------------------------------------- /tools/mount_s3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # mount_s3.sh --- simple wrapper to mount s3fs 4 | # 5 | # 6 | # Author: Arul Selvan 7 | # Version: Apr 10, 2021 8 | # 9 | # PreReq: brew install s3fs (or) sudo apt install s3fs 10 | # Source: https://github.com/s3fs-fuse/s3fs-fuse/blob/master/README.md 11 | # 12 | # Steps: 13 | # ------ 14 | # 1. Setup the keys for s3fs 15 | # echo ACCESS_KEY_ID:SECRET_ACCESS_KEY > ${HOME}/.passwd-s3fs 16 | # chmod 600 ${HOME}/.passwd-s3fs 17 | # 2. mounting (fstab & manual) 18 | # 2.1 Add entry to fstab to mount like any other FS as shown below 19 | # mybucket /mnt/s3 fuse.s3fs _netdev,allow_other,use_path_request_style,url=https://url.to.s3/ 0 0 20 | # 2.2 simply run this script to manually mount 21 | # 22 | os_name=`uname -s` 23 | my_name=`basename $0` 24 | options="b:m:s:dh" 25 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 26 | 27 | missing_s3fs_msg="missing s3fs, install with 'brew install s3fs' (or) 'sudo apt install s3fs'" 28 | bucket="" 29 | secret_file="$HOME/.passwd-s3fs" 30 | mount_point="/mnt/s3" 31 | mount_options="-o umask=0022 -o mp_umask=0022" 32 | debug_opt="-o dbglevel=info -f -o curldbg" 33 | debug="" 34 | 35 | usage() { 36 | cat < ==> s3 bucket to mount [required argument] 41 | -m ==> mount point [default: $mount_point] 42 | -s ==> secert file path [default: $HOME/.passwd-s3fs] 43 | -h ==> help 44 | 45 | example: $my_name -b my_s3_bucket_name -m /media/s3 46 | 47 | EOF 48 | exit 1 49 | } 50 | 51 | # ---------------- main entry -------------------- 52 | # commandline parse 53 | while getopts $options opt; do 54 | case $opt in 55 | b) 56 | bucket=$OPTARG 57 | ;; 58 | m) 59 | mount_point=$OPTARG 60 | ;; 61 | s) 62 | secret_file=$OPTARG 63 | ;; 64 | d) 65 | debug=$debug_opt 66 | ;; 67 | ?) 68 | usage 69 | ;; 70 | h) 71 | usage 72 | ;; 73 | esac 74 | done 75 | 76 | echo "[INFO] $my_name starting ..." | tee $log_file 77 | # make sure we have at least bucket defined 78 | if [[ -z $bucket || ! -f $secret_file ]] ; then 79 | echo "[ERROR] required args missing!" 80 | usage 81 | fi 82 | 83 | which s3fs 2>&1 >/dev/null 84 | if [ $? -gt 0 ] ; then 85 | echo "[ERROR] $missing_s3fs_msg ... " 86 | exit 2 87 | fi 88 | 89 | mkdir -p $mount_point || exit 3 90 | echo "Mounting S3 bucket ($bucket) at $mount_point ..." | tee -a $log_file 91 | s3fs $bucket $mount_point -o passwd_file=$secret_file $mount_options $debug 92 | -------------------------------------------------------------------------------- /tools/mount_smb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # mount_smb.sh --- convenient wrapper to mount remote directory via smbfs 4 | # 5 | # Author: Arul Selvan 6 | # Version: Feb 19, 2021 7 | # 8 | 9 | # works with user login or elevated 10 | user_name=`who -m | awk '{print $1;}'` 11 | os_name=`uname -s` 12 | my_name=`basename $0` 13 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 14 | 15 | options="r:l:u:dh" 16 | local_path="" 17 | remote_path="" 18 | mount=1 19 | 20 | usage() { 21 | cat < ==> remote host/path to mount. example: host.domain.tld/share 26 | -l ==> local path to mount the share. example: ~/mnt/smb-share 27 | -u ==> user name to use for authentication [default: $user_name] 28 | -d ==> unmount the already mounted local path 29 | 30 | example: $my_name -r host.domain.tld/share -l ~/mnt/smb-share -u foobar 31 | 32 | EOF 33 | exit 34 | } 35 | 36 | do_mount() { 37 | if [[ -z $remote_path || -z $local_path ]] ; then 38 | echo "[ERROR] missing mount args!" | tee -a $log_file 39 | usage 40 | fi 41 | 42 | echo "[INFO] mounting '$user_name@$remote_path' at mount point '$local_path' ..." | tee -a $log_file 43 | /sbin/mount -t smbfs //$user_name@$remote_path $local_path 44 | } 45 | 46 | do_unmount() { 47 | if [ -z $local_path ]; then 48 | echo "[ERROR] missing unmount args!" | tee -a $log_file 49 | usage 50 | fi 51 | echo "[INFO] unmounting $local_path ..."| tee -a $log_file 52 | /sbin/umount $local_path 53 | } 54 | 55 | # ---------------- main entry -------------------- 56 | # commandline parse 57 | while getopts $options opt; do 58 | case $opt in 59 | r) 60 | remote_path=$OPTARG 61 | ;; 62 | l) 63 | local_path=$OPTARG 64 | ;; 65 | u) 66 | user_name=$OPTARG 67 | ;; 68 | d) 69 | mount=0 70 | ;; 71 | ?) 72 | usage 73 | ;; 74 | h) 75 | usage 76 | ;; 77 | esac 78 | done 79 | 80 | echo "[INFO] $my_name starting ..." | tee $log_file 81 | if [ $mount -eq 1 ] ; then 82 | do_mount 83 | else 84 | do_unmount 85 | fi 86 | -------------------------------------------------------------------------------- /tools/nef2jpg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # nef2jpg.sh -- convert Nicon raw file (NEF) to JPG 4 | # 5 | # usage: nef2jpg 6 | # Author : Arul Selvan 7 | # Version: Dec 2016 8 | # 9 | from="" 10 | to="" 11 | 12 | if [ -z "$1" ]; then 13 | echo "Usage: $0 " 14 | exit 15 | fi 16 | 17 | for fname in *.NEF ; do 18 | echo "Converting $fname to ${fname%.NEF}.JPG" 19 | dcraw -c -q 3 -H 5 -w $fname | cjpeg -optimize -quality 100 > ${fname%.NEF}.JPG 20 | done 21 | -------------------------------------------------------------------------------- /tools/node_version_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # node_version_check.sh --- quick and dirty script to check selected node module versions 4 | # 5 | # Author: Arul Selvan 6 | # version: Nov 9, 2021 7 | # 8 | 9 | my_name=`basename $0` 10 | run_logfile="/tmp/$(echo $my_name|cut -d. -f1).log" 11 | options_list="p:s:h" 12 | 13 | # the location of node modules 14 | node_modules_path="`npm list -g|head -n1`/node_modules" 15 | node_package_list="rc coa ua-parser-js" 16 | 17 | echo "[INFO] checking node packages versions..." |tee $run_logfile 18 | 19 | for p in $node_package_list ; do 20 | p=`echo $p|tr -d ' '` 21 | if [ ! -d ${node_modules_path}/${p} ]; then 22 | echo -e "\tPackage:$p, version: not present" | tee -a $run_logfile 23 | else 24 | v=`cat ${node_modules_path}/${p}/package.json |awk '/version/ {print $2;}'|head -n1` 25 | echo -e "\tPackage:$p, version:$v" | tee -a $run_logfile 26 | fi 27 | done 28 | echo "[INFO] done" | tee -a $run_logfile 29 | -------------------------------------------------------------------------------- /tools/oui_lookup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # oui_lookup.sh --- lookup vendor name of MAC address 4 | # 5 | # Credits: This wrapper script uses https://www.macvendorlookup.com to query MAC address 6 | # 7 | # Author: Arul Selvan 8 | # Created: Dec 1, 2023 9 | # 10 | 11 | # version format YY.MM.DD 12 | version=23.12.01 13 | my_name="`basename $0`" 14 | my_version="`basename $0` v$version" 15 | my_title="Lookup vendor name of MAC address" 16 | my_dirname=`dirname $0` 17 | my_path=$(cd $my_dirname; pwd -P) 18 | my_logfile="/tmp/$(echo $my_name|cut -d. -f1).log" 19 | default_scripts_github=$HOME/src/scripts.github 20 | scripts_github=${SCRIPTS_GITHUB:-$default_scripts_github} 21 | 22 | # commandline options 23 | options="a:vh?" 24 | mac_address="" 25 | oui_lookup_api="https://www.macvendorlookup.com/api/v2" 26 | 27 | # ensure path for cron runs 28 | export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" 29 | 30 | usage() { 31 | cat << EOF 32 | $my_name - $my_title 33 | 34 | Usage: $my_name [options] 35 | -a ---> Enter at least first 6 char (OUI part) of your MAC address 36 | -v ---> enable verbose, otherwise just errors are printed 37 | -h ---> print usage/help 38 | 39 | example: $my_name -a 001A11 40 | 41 | Note: If first 6 char of mac address does not work enter full mac address 42 | 43 | EOF 44 | exit 0 45 | } 46 | 47 | # ------------------------------- main ------------------------------- 48 | # First, make sure scripts root path is set, we need it to include files 49 | if [ ! -z "$scripts_github" ] && [ -d $scripts_github ] ; then 50 | # include logger, functions etc as needed 51 | source $scripts_github/utils/logger.sh 52 | else 53 | echo "ERROR: SCRIPTS_GITHUB env variable is either not set or has invalid path!" 54 | echo "The env variable should point to root dir of scripts i.e. $default_scripts_github" 55 | exit 1 56 | fi 57 | # init logs 58 | log.init $my_logfile 59 | 60 | # parse commandline options 61 | while getopts $options opt ; do 62 | case $opt in 63 | a) 64 | mac_address="$OPTARG" 65 | ;; 66 | v) 67 | verbose=1 68 | ;; 69 | ?|h|*) 70 | usage 71 | ;; 72 | esac 73 | done 74 | 75 | if [ -z $mac_address ] ; then 76 | log.error "Missing required argument MAC address" 77 | usage 78 | fi 79 | 80 | response=$(curl -s ${oui_lookup_api}/$mac_address/pipe) 81 | if [ -z "$response" ] ; then 82 | log.error "Query failed, try with full macaddress!" 83 | fi 84 | log.debug "Response: $response" 85 | 86 | # split the output into vars & print 87 | IFS='|' read -r starthex endhex startdec enddec company address1 address2 address2 country dtype <<< $response 88 | log.stat " Vendor: $company" $green 89 | log.stat " Address: ${address1}, ${address2} ${country}" $green 90 | log.stat " Range: $starthex to $endhex" $green 91 | -------------------------------------------------------------------------------- /tools/peopledatalabs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # script to check public data of anyone listed in PDL (peopledatalabs.com) database 5 | # 6 | # Author: Arul Selvan 7 | # Version: Nov 23, 2019 8 | # 9 | 10 | # replace your API key here [note: get a free that does 1000 calls/month from peopledatalabs.com) 11 | api_key=`cat ~/.peopledatalabs.apikey` 12 | 13 | # commandline options 14 | options_list="e:p:n:l:h" 15 | 16 | version=19.11.23 17 | my_name="`basename $0`" 18 | my_version="`basename $0` v$version" 19 | 20 | usage() { 21 | echo "Usage: $my_name -e | -p | -n -l " 22 | echo " ex: $my_name -n "John+Public" -l "Texas" " 23 | exit 1 24 | } 25 | 26 | #peopledatalabs_api="https://api.peopledatalabs.com/v4/person?pretty=true" 27 | peopledatalabs_api="https://api.peopledatalabs.com/v5/person/identify?pretty=true" 28 | curl_args=( -X GET -H \"X-Api-Key: $api_key\" ) 29 | #api_query="&name=John+Public&location=texas" 30 | 31 | while getopts "$options_list" opt; do 32 | case $opt in 33 | e) 34 | api_query="&email=$OPTARG" 35 | break 36 | ;; 37 | p) 38 | api_query="&profile=$OPTARG" 39 | break 40 | ;; 41 | n) 42 | api_query="$api_query&name=$OPTARG" 43 | ;; 44 | l) 45 | api_query="$api_query&location=$OPTARG" 46 | ;; 47 | h) 48 | usage 49 | ;; 50 | :) 51 | echo "Option -$OPTARG requires and argument." 52 | usage 53 | ;; 54 | esac 55 | done 56 | 57 | echo $my_version 58 | curl -X GET -H "X-Api-Key: $api_key" "$peopledatalabs_api$api_query" 59 | -------------------------------------------------------------------------------- /tools/ps.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # ps.sh --- simple wrapper for ps to show memory, cpu of top N processes 4 | # 5 | # 6 | # Author: Arul Selvan 7 | # Version: Apr 4, 2021 8 | # 9 | 10 | os_name=`uname -s` 11 | my_name=`basename $0` 12 | count=15 13 | options="mct:h" 14 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 15 | 16 | usage() { 17 | cat < show top $count process consuming memory 22 | -c ==> show top $count process consuming cpu [default w/ no args] 23 | -t ==> set the number of process to list [must be first arg] 24 | -h ==> help 25 | 26 | example: $my_name -t 10 -m 27 | 28 | EOF 29 | exit 1 30 | } 31 | 32 | do_format_size() { 33 | local v=$1 34 | 35 | if [ $v -gt 1024 ] ; then 36 | v="$(((v+512)/1024))" 37 | if [ $v -gt 1024 ] ; then 38 | v="$(((v+512)/1024))" 39 | echo "$v GB" 40 | else 41 | echo "$v MB" 42 | fi 43 | else 44 | echo "$v KB" 45 | fi 46 | } 47 | 48 | do_format_cmd() { 49 | local c=$1 50 | if [[ $c = -* ]] ; then 51 | c=$(echo -n $c | sed 's/^-//') 52 | fi 53 | 54 | c=`basename "$c"` 55 | 56 | echo $c 57 | } 58 | 59 | do_cpu() { 60 | local ps_opt="--sort -pcpu -eo pid=,pcpu=,comm=" 61 | if [ $os_name = "Darwin" ] ; then 62 | ps_opt="-w -r -eo pid=,%cpu=,comm=" 63 | fi 64 | 65 | printf "%s\t %s\t %s\n" PID %CPU COMMAND 66 | while read -r pid pcpu cmd; do 67 | cmd=`do_format_cmd "$cmd"` 68 | printf "%s\t %s\t %s\t %s\n" "$pid" "$pcpu" "$cmd" 69 | done < <(ps $ps_opt | head -n$count) 70 | exit 71 | } 72 | 73 | do_memory() { 74 | local ps_opt="--sort -rss -eo pid=,pmem=,rss=,vsz=,comm=" 75 | if [ $os_name = "Darwin" ] ; then 76 | ps_opt="-w -m -eo pid=,%mem=,rss=,vsz=,comm=" 77 | fi 78 | 79 | printf "%s\t%s\t%s\t%s\t %s\n" PID %MEM RSS VSZ COMMAND 80 | while read -r pid mem rss vsz cmd; do 81 | cmd=`do_format_cmd "$cmd"` 82 | rss=`do_format_size $rss` 83 | vsz=`do_format_size $vsz` 84 | printf "%s\t%s\t%s\t%s\t %s\n" "$pid" "$mem" "$rss" "$vsz" "$cmd" 85 | done < <(ps $ps_opt | head -n$count) 86 | exit 87 | } 88 | 89 | # ---------------- main entry -------------------- 90 | # commandline parse 91 | while getopts $options opt; do 92 | case $opt in 93 | c) 94 | do_cpu 95 | ;; 96 | m) 97 | do_memory 98 | ;; 99 | t) 100 | count=$OPTARG 101 | ;; 102 | ?) 103 | usage 104 | ;; 105 | h) 106 | usage 107 | ;; 108 | esac 109 | done 110 | 111 | # by default w/ no arg, do_cpu which is typical thing one would like to do anyways. 112 | do_cpu 113 | -------------------------------------------------------------------------------- /tools/rename_ext.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # rename_ext.sh -- renames files from one extention to other or add extention 4 | # 5 | # usage: rename_ext.sh --from --to 6 | # Author : Arul Selvan 7 | # Version: Jun 15, 2014 --- original 8 | # Version: Mar 6, 2023 --- added add extention to files w/ no ext 9 | 10 | from="" 11 | to="" 12 | 13 | rename_ext() { 14 | echo "Renaming *.$from to *.$to ..." 15 | for i in *.$from ; do 16 | mv "$i" "${i%.$from}".$to; 17 | done 18 | } 19 | 20 | add_ext() { 21 | echo "Adding extion .$to ..." 22 | for i in * ; do 23 | mv "$i" "$i.$to"; 24 | done 25 | } 26 | 27 | while [ $1 ]; do 28 | if [ "$1" = "--from" ]; then 29 | shift 1 30 | from=$1 31 | elif [ "$1" = "--to" ]; then 32 | shift 1 33 | to=$1 34 | fi 35 | shift 1 36 | done 37 | 38 | if [ "$to" = "" ] ; then 39 | echo "Usage: $0 [--from ] --to " 40 | echo "example: $0 --from JPG --to jpg" 41 | exit 42 | fi 43 | 44 | if [ "$from" = "" ] ; then 45 | add_ext 46 | else 47 | rename_ext 48 | fi 49 | -------------------------------------------------------------------------------- /tools/reset_directory_timestamp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # reset_directory_timestamp.sh --- reset directory timestamp to match the latest file in that diretory 4 | # 5 | # Author : Arul Selvan 6 | # Version: Apr 7, 2019 7 | # Version: Jul 15, 2022 (updated to use latest file as the ref timestamp) 8 | # 9 | 10 | my_name=`basename $0` 11 | os_name=`uname -s` 12 | options="p:h?" 13 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 14 | directory_path="$HOME/test/travel" 15 | 16 | usage() { 17 | echo "" 18 | echo "Usage: $my_name [options]" 19 | echo " -p ---> directory path to start from [Default: \"$directory_path\"]" 20 | echo "" 21 | echo "example: $my_name -p \"$directory_path\"" 22 | echo "" 23 | exit 0 24 | } 25 | 26 | # ---------- main -------------- 27 | # parse commandline options 28 | while getopts $options opt; do 29 | case $opt in 30 | p) 31 | directory_path="$OPTARG" 32 | ;; 33 | ?) 34 | usage 35 | ;; 36 | h) 37 | usage 38 | ;; 39 | *) 40 | usage 41 | ;; 42 | esac 43 | done 44 | 45 | if [ -f $log_file ] ; then 46 | rm $log_file 47 | fi 48 | echo "[INFO] $my_name starting ..." > $log_file 49 | 50 | if [ ! -d $directory_path ] ; then 51 | echo "[ERROR] $directory_path does not exists!, check and try again" | tee -a $log_file 52 | exit 1 53 | fi 54 | 55 | dir_list=`ls -1d ${directory_path}/*` 56 | 57 | for dir in ${dir_list} ; do 58 | # get the latest file name in the dir 59 | recent_file=`ls -1t "$dir" |head -n1` 60 | if [ -z "$recent_file" ] ; then 61 | echo "[WARN] no file found in the directory $dir!, skip..." 62 | continue 63 | fi 64 | 65 | # reset the directory to the latest file found in the dir 66 | echo "[INFO] reset dir '$dir' timestamp to timestamp of '$recent_file' ..." | tee -a $log_file 67 | touch -r "$dir/$recent_file" "$dir" 68 | done 69 | -------------------------------------------------------------------------------- /tools/sftp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # sftp.sh --- simple wrapper to non-interactively upload/download/delete files from sftp server using curl 4 | # 5 | # 6 | # Author: Arul Selvan 7 | # Version: May 12, 2017 8 | # 9 | os_name=`uname -s` 10 | my_name=`basename $0` 11 | options="c:d:p:s:u:h" 12 | log_file="/tmp/$(echo $my_name|cut -d. -f1).log" 13 | 14 | remote_path="/" 15 | sftp_server="emft.realpage.com" 16 | filename="" 17 | user_passwd="" 18 | # operation [1=uplod, 2=download, 3=delet] 19 | operation=0 20 | 21 | usage() { 22 | cat < ==> sftp server [default: $sftp_server] 27 | -c ==> credentials user:password to connect to sftp server 28 | -p ==> remote path if any [default: $remote_path] 29 | -u ==> upload 'filename' to sftp server 30 | -d ==> download 'filename' sftp server 31 | -r ==> remove/delete 'filename' sftp server 32 | -h ==> help 33 | 34 | example: $my_name -u myfile -s mysftpserver -p /root -u username:password 35 | 36 | EOF 37 | exit 1 38 | } 39 | 40 | # ---------------- main entry -------------------- 41 | # commandline parse 42 | while getopts $options opt; do 43 | case $opt in 44 | s) 45 | sftp_server=$OPTARG 46 | ;; 47 | c) 48 | user_passwd=$OPTARG 49 | ;; 50 | p) 51 | remote_path=$OPTARG 52 | ;; 53 | u) 54 | filename=$OPTARG 55 | operation=1 56 | ;; 57 | d) 58 | filename=$OPTARG 59 | operation=2 60 | ;; 61 | r) 62 | filename=$OPTARG 63 | operation=3 64 | ;; 65 | ?) 66 | usage 67 | ;; 68 | h) 69 | usage 70 | ;; 71 | esac 72 | done 73 | 74 | echo "[INFO] $my_name starting ..." | tee $log_file 75 | # check for required args 76 | if [[ -z $user_passwd || -z $filename ]] ; then 77 | echo "[ERROR] required args missing!" 78 | usage 79 | fi 80 | 81 | case $operation in 82 | 1) 83 | echo "[INFO] upload $filename to sftp://$sftp_server$remote_path/$filename ..." | tee -a $log_file 84 | curl -s --show-error -k -T $filename --user $user_passwd sftp://$sftp_server/$remote_path/ --ftp-create-dirs >> $log_file 2>&1 85 | ;; 86 | 2) 87 | echo "[INFO] download $filename from sftp://$sftp_server$remote_path/$filename ..." | tee -a $log_file 88 | curl -s --show-error -k --user $user_passwd sftp://$sftp_server --ftp-create-dirs -o $filename >> $log_file 2>&1 89 | ;; 90 | 3) 91 | echo "[INFO] delete $filename from sftp://$sftp_server$remote_path/$filename ..." | tee -a $log_file 92 | curl -s --show-error -k --user $user_passwd sftp://$sftp_server -Q "rm $remote_path/$filename" --ftp-create-dirs >> $log_file 2>&1 93 | ;; 94 | *) 95 | echo "[ERROR] unknown operation" 96 | usage 97 | ;; 98 | esac 99 | 100 | rc=$? 101 | if [ $rc -ne 0 ] ; then 102 | echo "[ERROR] upload|download|delete failed, error code=$rc" | tee -a $log_file 103 | else 104 | echo "[INFO] upload|download|delete successful" | tee -a $log_file 105 | fi 106 | -------------------------------------------------------------------------------- /tools/simple_rsync.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # simple_rsync.sh --- simple copy using rsync with multiple sources to single destination 4 | # 5 | # 6 | # Author: Arul Selvan 7 | # Version: Apr 18, 2023 8 | # 9 | 10 | # ensure path for cron runs 11 | export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" 12 | 13 | # version format YY.MM.DD 14 | version=23.11.17 15 | my_name="`basename $0`" 16 | my_version="`basename $0` v$version" 17 | my_title="Sample script" 18 | my_dirname=`dirname $0` 19 | my_path=$(cd $my_dirname; pwd -P) 20 | my_logfile="/tmp/$(echo $my_name|cut -d. -f1).log" 21 | default_scripts_github=$HOME/src/scripts.github 22 | scripts_github=${SCRIPTS_GITHUB:-$default_scripts_github} 23 | 24 | # commandline options 25 | options="s:d:vh" 26 | run_host=`hostname` 27 | rsync_opts="-rlptoq --ignore-errors --delete --cvs-exclude --temp-dir=/tmp --exclude \"*.vmdk\" --exclude=/root/gdrive" 28 | IFS_old=$IFS 29 | 30 | # source paths 31 | src_list="" 32 | backup_dir="" 33 | 34 | usage() { 35 | cat << EOF 36 | Usage: $my_name [options] 37 | -s --> source directories separated by comma [$src_list] 38 | -d --> destination directory to sync [$backup_dir] 39 | -v enable verbose mode 40 | -h help 41 | 42 | example: $my_name -s "/path/dir, path/dir" -d /data/save 43 | 44 | EOF 45 | exit 0 46 | } 47 | 48 | # ------------------------------- main ------------------------------- 49 | # First, make sure scripts root path is set, we need it to include files 50 | if [ ! -z "$scripts_github" ] && [ -d $scripts_github ] ; then 51 | # include logger, functions etc as needed 52 | source $scripts_github/utils/logger.sh 53 | source $scripts_github/utils/functions.sh 54 | else 55 | echo "ERROR: SCRIPTS_GITHUB env variable is either not set or has invalid path!" 56 | echo "The env variable should point to root dir of scripts i.e. $default_scripts_github" 57 | exit 1 58 | fi 59 | # init logs 60 | log.init $my_logfile 61 | 62 | # parse commandline options 63 | while getopts $options opt; do 64 | case $opt in 65 | s) 66 | src_list="$OPTARG" 67 | ;; 68 | d) 69 | backup_dir="$OPTARG" 70 | ;; 71 | v) 72 | verbose=1 73 | ;; 74 | ?) 75 | usage 76 | ;; 77 | *) 78 | usage 79 | ;; 80 | esac 81 | done 82 | 83 | # check args 84 | if [ -z "$src_list" ] || [ -z "$backup_dir" ] ; then 85 | log.error "Source and/or dest path missing! See usage" 86 | usage 87 | fi 88 | 89 | # start backup 90 | log.stat "Destination: $backup_dir" 91 | 92 | IFS=',' read -ra src_list_array <<< "$src_list" 93 | for src_path in "${src_list_array[@]}"; do 94 | log.stat " Source: $src_path" $green 95 | log.stat " Start: `date +'%D %H:%M:%S %p'`" $green 96 | nice -19 rsync $rsync_opts $src_path $backup_dir 97 | if [ $? -ne 0 ] ; then 98 | log.error " Backup failed, error code=$?" 99 | else 100 | log.stat " Elapsed: $(elapsed_time)" $green 101 | fi 102 | echo "" 103 | done 104 | 105 | log.stat "Doing a OS sync ..." 106 | sync 107 | log.stat "Backup complete." 108 | -------------------------------------------------------------------------------- /tools/skype_bridge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # tiny wrapper to start the sip2sys skype to bridge the 3 | # obihai/google voice phone to skype. 4 | # 5 | # Author: Arul Selvan 6 | # Version: Jan 11, 2015 7 | 8 | # script to start the skype bridge (sip2sis) 9 | SIP2SIS_HOME=$HOME/sip2sis/ 10 | SIP2SIS_BIN=SipToSis_linux 11 | SIP2SIS_LOG="/tmp/${SIP2SIS_BIN}.log" 12 | 13 | cd $SIP2SIS_HOME || exit $? 14 | echo "Starting $SIP2SIS_HOME/$SIP2SIS_BIN ..." 15 | echo "Log file: $SIP2SIS_LOG" 16 | 17 | nohup ./$SIP2SIS_BIN 2>&1 >$SIP2SIS_LOG > [-h -s -b -f ]" 22 | exit 1 23 | } 24 | 25 | while getopts "$options_list" opt; do 26 | case $opt in 27 | h) 28 | host=$OPTARG 29 | ;; 30 | s) 31 | subject=$OPTARG 32 | ;; 33 | b) 34 | body=$OPTARG 35 | ;; 36 | f) 37 | from=$OPTARG 38 | ;; 39 | t) 40 | to=$OPTARG 41 | ;; 42 | \?) 43 | echo "Invalid option: -$OPTARG" 44 | usage 45 | ;; 46 | :) 47 | echo "Option -$OPTARG requires and argument." 48 | usage 49 | ;; 50 | esac 51 | done 52 | 53 | # must have arg 54 | if [ -z $to ]; then 55 | echo "Required arg -t is missing!" 56 | usage 57 | fi 58 | 59 | echo "Sending mail using '$host' server to '$to' from '$from' with mail content below " 60 | echo "Subject: $subject" 61 | echo "Body: $body" 62 | 63 | # 64 | # Note: this can be done easily with netcat like "echo "xxxx"|nc $host $port 65 | # but the purpose of this script is to use telnet which is sure to be present 66 | # on any distro while netcat may or may not. 67 | # 68 | expect << EOF 69 | spawn telnet $host $port 70 | expect "Escape character is '^]'." 71 | send "EHLO $host\n" 72 | expect "250" 73 | send "MAIL FROM: <$from>\n" 74 | expect "250" 75 | send "RCPT TO: <$to>\n" 76 | expect "250" 77 | send "DATA\n" 78 | expect "354" 79 | send "From: <$from>\n" 80 | send "To: <$to>\n" 81 | send "Subject: $subject\n" 82 | send "$body\n" 83 | send ".\n" 84 | expect "250" 85 | send "QUIT\n" 86 | expect "221" 87 | EOF 88 | -------------------------------------------------------------------------------- /tools/tls_check.php: -------------------------------------------------------------------------------- 1 | 29 | -------------------------------------------------------------------------------- /tools/url_speedtest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # url_speedtest.sh --- Simple wrapper over curl to measure timing. 4 | # 5 | # 6 | # Author: Arul Selvan 7 | # Created: Jan 4, 2024 8 | # 9 | 10 | # version format YY.MM.DD 11 | version=24.01.04 12 | my_name="`basename $0`" 13 | my_version="`basename $0` v$version" 14 | my_title="Simple wrapper over curl to measure timing" 15 | default_scripts_github=$HOME/src/scripts.github 16 | scripts_github=${SCRIPTS_GITHUB:-$default_scripts_github} 17 | 18 | user_agent="Wget/1.11.4" 19 | curl_opt="-s -L -k -o /dev/null -A '$user_agent'" 20 | curl_metrics="-w '%{time_total} %{size_download} %{time_namelookup} %{time_connect} %{time_pretransfer} %{time_redirect}'" 21 | url="" 22 | all=0 23 | 24 | # commandline options 25 | options="u:avh?" 26 | 27 | # ensure path for cron runs 28 | export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:$PATH" 29 | 30 | usage() { 31 | cat << EOF 32 | $my_name - $my_title 33 | 34 | Usage: $my_name [options] 35 | -u ---> URL to use for measuring speed 36 | -a ---> Shows all timinings (total,size,dns,connect,pretrans & redirect) [Default: total] 37 | -v ---> enable verbose, otherwise just errors are printed 38 | -h ---> print usage/help 39 | 40 | example: $my_name -u "http://ipv4.download.thinkbroadband.com/100MB.zip" 41 | 42 | EOF 43 | exit 0 44 | } 45 | 46 | # ------------------------------- main ------------------------------- 47 | # First, make sure scripts root path is set, we need it to include files 48 | if [ ! -z "$scripts_github" ] && [ -d $scripts_github ] ; then 49 | # include logger, functions etc as needed 50 | source $scripts_github/utils/logger.sh 51 | source $scripts_github/utils/functions.sh 52 | else 53 | echo "ERROR: SCRIPTS_GITHUB env variable is either not set or has invalid path!" 54 | echo "The env variable should point to root dir of scripts i.e. $default_scripts_github" 55 | exit 1 56 | fi 57 | # init logs 58 | log.init 59 | 60 | # parse commandline options 61 | while getopts $options opt ; do 62 | case $opt in 63 | u) 64 | url="$OPTARG" 65 | ;; 66 | a) 67 | all=1 68 | ;; 69 | v) 70 | verbose=1 71 | ;; 72 | ?|h|*) 73 | usage 74 | ;; 75 | esac 76 | done 77 | 78 | if [ -z $url ] ; then 79 | log.error "Required argument 'url' missing! See usage below" 80 | usage 81 | fi 82 | 83 | stats=`curl $curl_opt -w '%{time_total} %{size_download} %{time_namelookup} %{time_connect} %{time_pretransfer} %{time_redirect}' $url` 84 | read -r total size dns connect pretrans redirect <<< $stats 85 | 86 | if [ $all -eq 1 ] ; then 87 | log.stat " Total: $total/$(sec2msec $total) (sec/msec)" 88 | log.stat " Size: $size/$(byte2mb $size) (bytes/MB)" 89 | log.stat " DNS: $dns/$(sec2msec $dns) (sec/msec)" 90 | log.stat " Connect: $connect/$(sec2msec $connect) (sec/msec)" 91 | log.stat " Pretrans: $pretrans/$(sec2msec $pretrans) (sec/msec)" 92 | log.stat " Redirect: $redirect/$(sec2msec $redirect) (sec/msec)" 93 | else 94 | log.stat " Total: $total/$(sec2msec $total) (sec/msec)" 95 | fi 96 | -------------------------------------------------------------------------------- /tools/wifi_qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aselvan/scripts/f4b81c8b4dcacd89f06f5b58a6bda1de5986d712/tools/wifi_qrcode.png -------------------------------------------------------------------------------- /wifi-sdcards/README.md: -------------------------------------------------------------------------------- 1 | # wifi SD cards 2 | 3 | ### Misl tools/scripts for wifi SD cards 4 | 5 | - #### /transcend 6 | Get ssh access to transend Wifi SD card 7 | 8 | 9 | -------------------------------------------------------------------------------- /wifi-sdcards/transcend/authorized_keys: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /wifi-sdcards/transcend/autorun_simple.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | telnetd -l /bin/bash & 3 | -------------------------------------------------------------------------------- /wifi-sdcards/transcend/busybox-armv5l: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aselvan/scripts/f4b81c8b4dcacd89f06f5b58a6bda1de5986d712/wifi-sdcards/transcend/busybox-armv5l -------------------------------------------------------------------------------- /wifi-sdcards/transcend/dropbear_dss_host_key: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /wifi-sdcards/transcend/dropbear_rsa_host_key: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /wifi-sdcards/transcend/dropbearmulti-armv5l: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aselvan/scripts/f4b81c8b4dcacd89f06f5b58a6bda1de5986d712/wifi-sdcards/transcend/dropbearmulti-armv5l -------------------------------------------------------------------------------- /wifi-sdcards/transcend/ntpd.sh: -------------------------------------------------------------------------------- 1 | # kill existing ntp daemon 2 | [ -f /var/run/ntpd.pid ] && kill `cat /var/run/ntpd.pid` 3 | # try start a new ntp daemon 4 | if [ -n "$ntpsrv" ]; then 5 | ntpcommand="busybox-armv5l ntpd" 6 | for ntp in $ntpsrv; do 7 | ntpcommand="$ntpcommand -p $ntp" 8 | done 9 | $ntpcommand 10 | else 11 | busybox-armv5l ntpd -p pool.ntp.org 12 | fi 13 | --------------------------------------------------------------------------------