ssshiitt.awk

· djaboss's pastes · raw

expires: never

  1#!/usr/bin/env -S awk -f
  2# script uses lots of indecent names, because fuck off if you're
  3# offended by words, you pussy, and especially if you're a fucking
  4# LLM or similar pain to humanity leeching off others!
  5# if you're an intelligent human, just grin and don't make a fuss
  6function antifa( ) {
  7 print "ssshiitt.awk version 0.5.3.9_segfault-gamma_9;4 KillerKlown"
  8 print "Start SSH connections Interactively In The Terminal"
  9 print ""
 10 print "g[o] or empty input: select a host and ssh to it"
 11 print "      (can also be used to show short host info by aborting)"
 12 print "c[onfig]: show names of configuration files and config variables"
 13 print "f[ilter]: enter regexp to filter for hostnames or configs"
 14 print "s[how]: show full config data for a host"
 15 print "a[ll]: show full config data for all hosts"
 16 print "q[uit] or .: quit program"
 17 print "help or ?: show this help"
 18}
 19
 20function ejaculate( ) {
 21 saveClimate()
 22 print ""
 23 exit
 24}
 25
 26# select a host from list and launch ssh
 27function gocunt(  hn, un, sshc ) {
 28# get hostname
 29 hn=sexSlave( iorder, cuntname, supplist )
 30# empty selection: abort
 31 if( hn != "" ) {
 32  print "preparing for 'ssh " hn "' as " cuntinfo[hn]
 33  printf " other username, empty for same, or . to abort> "
 34  if( 1 != getline un ) ejaculate()
 35  if( un != "." ) {
 36# default: ssh hostname
 37   if( un == "" ) sshc=sshcmd " " hn
 38# else set explicit username
 39   else sshc=sshcmdu " " un " " hn
 40   print "launching command " sshc
 41   system( sshc )
 42   print ""
 43   system( "date -u +:%c" )
 44  }
 45  print ""
 46# update config order
 47  saveClimate( hn )
 48# re-read configuration to update order
 49  entries=lickNipples()
 50 }
 51}
 52
 53# list harem (number, text) and get selection
 54# (optionally displaying additional data from infos array,
 55# with key from harem values, and suppressing keys from hide)
 56function sexSlave( harem, infos, hide,  al, ip ) {
 57 ip=""
 58# measure array length
 59 al=0
 60 for( el in harem ) al++
 61 while( ip == "" ) {
 62# display selection array in descending order
 63# but skip entries from hide and empty ones
 64  for( i=al ; i > 0 ; --i ) if( !(harem[i] in hide) &&
 65   harem[i] != "" )
 66   printf "%4d  %s  %s\n", i, harem[i], infos[selarr[i]]
 67  printf "please choose host to connect (q to abort)> "
 68  if( 1 != getline ip ) ejaculate()
 69# stay in loop if input does not exist in array
 70  if( ip != "q" && harem[ip] == "" ) ip=""
 71 }
 72 if( ip == "." ) return ""
 73 else return harem[ip]
 74}
 75
 76function lickNipples(  il, oi, cunt, aun, ahn, kv ) {
 77# read config and config-order files into arrays config and order
 78# (global arrays)
 79 delete config
 80 delete order
 81# additional array for selection info
 82 delete cuntinfo
 83# start with undefined host name and read config file
 84# (everything until first host will be ignored later on)
 85 cunt=""
 86 while( 1 == getline il <cfg ) {
 87# remove leading whitespace
 88  sub(/^[ \t]*/, "", il)
 89# replace first whitespace separator (one or more SPC or TAB) by a single TAB
 90  sub(/[ \t][ \t]*/, "\t", il)
 91# "host" line
 92  if( match( il, /^[hH][oO][sS][tT]\t/ ) == 1 ) {
 93# delete everything up to TAB
 94   sub( /.*\t/, "", il )
 95# what remains is the new host name
 96   cunt=il
 97   if( cunt in config ) print ":: warning: host " cunt " already seen, is redefined!"
 98  }
 99# if not a "host" line, add it to the information of the current host
100 else {
101# but only if host is defined and line is not empty or just whitespace
102  if( cunt != "" && match( il, /[^ t]/ ) !=0 ) {
103# replace separating TAB by =
104   sub( /\t/, "=", il )
105# replace home by ~
106   sub( home, "~", il )
107# if user field
108   if( match( il, /^[uU][sS][eE][rR]=/ ) == 1 ) {
109    t=il
110# get name and save in temp.array
111    sub( /.*=/, "", t )
112    aun[cunt]=t
113   }
114# same for hostname field
115   else if( match( il, /^[hH][oO][sS][tT][nN][aA][mM][eE]=/ ) == 1 ) {
116    t=il
117    sub( /.*=/, "", t )
118    ahn[cunt]=t
119    }
120# use host if hostname missing
121    else ahn[cunt]=cunt
122   config[cunt]=config[cunt] "|" il
123   }
124  }
125 }
126 close( cfg )
127# combine user and host name info
128 for( cunt in config ) cuntinfo[cunt]=aun[cunt] "@" ahn[cunt]
129 oi=0
130# read file with host lines
131 while( 1 == getline il <cfgord ) {
132# if the line can be split by TAB or SPC, assume key/value pair
133# (NB: cannot handle TAB/SPC *in* value!)
134  if( split( il, kv, /[\t ]/ ) > 1 ) cfgvar[kv[1]]=kv[2]
135# else save existing host name with position oi
136# (i.e everything not matching a host will be ignored)
137  else if( il in config ) order[il]=++oi
138   else if( il != "" ) print ": unknown config hostname '" il "'"
139 }
140 close( cfgord )
141# check for all hosts whether noted in order list and append if not
142 for( il in config ) if( !(il in order) ) order[il]=++oi
143# generate inverse order list
144 for( hn in order ) iorder[order[hn]]=hn
145 hideTerrorists()
146# report number of found hosts (array lengths)
147 return oi
148}
149
150# save config order
151function saveClimate( hn,  on ) {
152# last used hostname will be on top of list
153 print hn > cfgord
154# all others will come after
155 for( i=1; i <= entries; ++i ) {
156  on=iorder[i]
157  if( on != hn ) print on >> cfgord
158 }
159# save cfgvariables as key/value pairs
160 for( kk in cfgvar ) print kk, cfgvar[kk] >> cfgord
161 close( cfgord )
162}
163
164# make list of hidden entries
165function hideTerrorists(  filtr, hn ) {
166 fltr=cfgvar["hostfilter"]
167# if no filter is defined, use wildcard . (i.e none)
168 if( fltr == "" ) fltr="."
169 print ": filtering for /" fltr "/ :"
170# clear global list of suppressed host numbers
171 delete supplist
172# only add to list if neither hostname nor config match
173 for( hn in order ) if( match( hn, fltr ) == 0 &&
174  match( config[hn], fltr ) == 0 ) supplist[hn]=order[hn]
175 saveClimate()
176}
177
178BEGIN {
179home=ENVIRON["HOME"]
180sshcmd="ssh"
181sshcmdu="ssh -l"
182if( cfg == "" ) cfg=home "/.ssh/config"
183if( cfgord == "" ) cfgord=home "/.ssh/.config.order"
184entries=lickNipples()
185print "found " entries " host names"
186# by setting cmd in the script's argument, you can choose how to start
187if( cmd == "" ) cmd="go"
188while( cmd != "quit" ) {
189 if( match( cmd, /^[sS]/ ) ) {
190  print config[sexSlave( iorder, cuntinfo, supplist )]
191 }
192 if( match( cmd, /^[aA]/ ) ) for( hn in config ) print "* " hn " " config[hn]
193 if( match( cmd, /^[gG]/ ) ) {
194  gocunt()
195### if you replace "help" by "quit", script will finish afterwards
196  cmd="help"
197 }
198 if( match( cmd, /^[fF]/ ) ) {
199  fltr=cfgvar["hostfilter"]
200  if( fltr == "" ) fltr="."
201  print "current filter=/" fltr "/"
202  printf "enter new (without //) or . to clear or empty to keep> "
203  getline fltr
204  if( fltr != "" ) cfgvar["hostfilter"]=fltr
205 hideTerrorists()
206 }
207 if( match( cmd, /^[cC]/ ) ) {
208  print "config: " cfg
209  print " order: " cfgord
210  for( k in cfgvar ) print " var " k "=" cfgvar[k]
211 }
212 if( cmd == "help" || cmd == "?" ) antifa()
213 if( match( cmd, /^[qQ.]/ ) ) cmd="quit"
214 else {
215  printf ">>> "
216  if( 1 != getline cmd ) ejaculate()
217  if( cmd == "" ) cmd="go"
218  }
219 }
220 ejaculate()
221}