├── .gitignore
├── CHANGELOG.md
├── bashrc
├── files
├── sudo
├── tar
├── update_title_bar
├── command_not_found_handle
├── again
├── addpath
└── ssh
├── README.md
├── README.ssh.md
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | *.sw*
2 | *~
3 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 2016-09-12
2 | SSH intercept function code cleanup.
3 | * Default config embedded into the function, rather than relying on an external call.
4 | * Default configuration overridden by declaring them as exported variables.
5 |
6 | ## 2016-09-09
7 | External 'sshiconf' function added to reduce size of ssh function.
8 | Update to ssh function to reduce size.
9 | * if;then conditionals replaced with shorthand versions.
10 | * Extra whitespace removed where possible, and keeping readablity in mind.
11 |
12 | ## 2016-09-08 #2
13 | Initial release of new intercept function for 'ssh'.
14 |
15 | ## 2016-09-08 #1
16 | Initial release of new intercept functions for 'tar' and 'sudo'.
17 |
18 | ## 2016-09-07
19 | Initial release of addpath function.
20 |
21 |
--------------------------------------------------------------------------------
/bashrc:
--------------------------------------------------------------------------------
1 | # Invocation for bashrc_enhancements files.
2 | #
3 | # Author: Jeremy Melanson
4 | #
5 | # Source-code, documentation and revision Git repository: https://github.com/zish/bashrc_enhancements
6 | #
7 | # $ git clone https://github.com/zish/bashrc_enhancements
8 | #
9 | #
10 | # This file is part of bashrc_enhancements.
11 | #
12 | # bashrc_enhancements is free software: you can redistribute it and/or modify
13 | # it under the terms of the GNU Affero General Public License as published by
14 | # the Free Software Foundation, either version 3 of the License, or
15 | # (at your option) any later version.
16 | #
17 | # bashrc_enhancements is distributed in the hope that it will be useful,
18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 | # GNU Affero General Public License for more details.
21 | #
22 | # You should have received a copy of the GNU Affero General Public License
23 | # along with bashrc_enhancements. If not, see .
24 |
25 | export ENHANCEMENTS_ROOT="${HOME}/.bashrc_enhancements"
26 | export ENHANCEMENTS_ENABLED=("addpath" "again" "command_not_found_handle" "ssh" "sudo" "update_title_bar" "tar")
27 |
28 | for F in ${ENHANCEMENTS_ENABLED[@]}; do
29 | [ -e ${ENHANCEMENTS_ROOT}/files/${F} ] && . ${ENHANCEMENTS_ROOT}/files/${F}
30 | done
31 |
--------------------------------------------------------------------------------
/files/sudo:
--------------------------------------------------------------------------------
1 | #-- SUDO interception command. This allows you to use your aliases with the sudo command.
2 | #
3 | # Author: Jeremy Melanson
4 | #
5 | # Source-code, documentation and revision Git repository: https://github.com/zish/bashrc_enhancements
6 | #
7 | # Last-Modified: 2016-09-08
8 | #
9 | # $ git clone https://github.com/zish/bashrc_enhancements
10 | #
11 | # To use this, source the file from your .bashrc (or .bash_profile).
12 | #
13 | #
14 | # This file is part of bashrc_enhancements.
15 | #
16 | # bashrc_enhancements is free software: you can redistribute it and/or modify
17 | # it under the terms of the GNU Affero General Public License as published by
18 | # the Free Software Foundation, either version 3 of the License, or
19 | # (at your option) any later version.
20 | #
21 | # bashrc_enhancements is distributed in the hope that it will be useful,
22 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | # GNU Affero General Public License for more details.
25 | #
26 | # You should have received a copy of the GNU Affero General Public License
27 | # along with bashrc_enhancements. If not, see .
28 |
29 | sudo () {
30 | local SCMD="/usr/bin/sudo"; local C=($@)
31 | local OIFS=${IFS}; IFS=$'\n'
32 | for A in $(alias); do
33 | [[ ${A} =~ ^alias\ ([[:alpha:]]*)\=\'(.*)\' ]]
34 | if [[ "${1}" == "${BASH_REMATCH[1]}" ]];then local C[0]="";SCMD="${SCMD} ${BASH_REMATCH[2]}"; fi
35 | done
36 | IFS=${OIFS}
37 | ${SCMD} ${C[@]}
38 | } # END sudo ()
39 |
--------------------------------------------------------------------------------
/files/tar:
--------------------------------------------------------------------------------
1 | #-- Tar interception command. Suppresses annoying "SCHILY" messages when extracting a TAR archive originating from a MacOS system.
2 | # This is primarily intended for Linux systems, but can be used for any system with GNU/Tar.
3 | # This cuts down the amount of output echoed to your terminal or output log,
4 | # and is expecially useful when extracting a tar file from MacOS with a lot of files.
5 | #
6 | # Author: Jeremy Melanson
7 | #
8 | # Source-code, documentation and revision Git repository: https://github.com/zish/bashrc_enhancements
9 | #
10 | # Last-Modified: 2016-09-08
11 | #
12 | # $ git clone https://github.com/zish/bashrc_enhancements
13 | #
14 | # To use this, source the file from your .bashrc (or .bash_profile).
15 | #
16 | #
17 | # This file is part of bashrc_enhancements.
18 | #
19 | # bashrc_enhancements is free software: you can redistribute it and/or modify
20 | # it under the terms of the GNU Affero General Public License as published by
21 | # the Free Software Foundation, either version 3 of the License, or
22 | # (at your option) any later version.
23 | #
24 | # bashrc_enhancements is distributed in the hope that it will be useful,
25 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
26 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 | # GNU Affero General Public License for more details.
28 | #
29 | # You should have received a copy of the GNU Affero General Public License
30 | # along with bashrc_enhancements. If not, see .
31 |
32 | tar () {
33 |
34 |
35 | local STDINSTDOUT=
36 | local TARBIN="$(which tar)"
37 |
38 | local CMD="${TARBIN}"
39 |
40 | local IFS=$'\n'
41 |
42 | #-- Retrieve options from "tar --help".
43 | # Long-style opts containing (COMMAND|DATE|DATE-OR-FILE|FILE|NAME|STRING|STYLE)
44 | # will have the value double-quoted.
45 | #
46 | R='^\ +(-[a-zA-Z]+,\ +)?(--[a-z\-]+=)(COMMAND|DATE(-OR-FILE)?|FILE|NAME|ST(RING|YLE))'
47 | declare -A QOPTS
48 |
49 | for L in $(${TARBIN} --help); do
50 | [[ "${L}" =~ ${R} ]] && QOPTS["${BASH_REMATCH[2]}"]=1 || true
51 |
52 | done
53 |
54 |
55 | for O in "${@}"; do
56 | #- "Short" style opts.
57 | [[ "${O}" =~ ^-[a-zA-Z] ]] && {
58 | CMD+=" ${O}"
59 |
60 | } || {
61 | #- "Long" style opts. Some have values that need double-quoting.
62 | [[ "${O}" =~ ^(--[a-z\-]+=?)(.*) ]] && {
63 | local ONAME="${BASH_REMATCH[1]}"
64 | local OVAL="${BASH_REMATCH[2]}"
65 |
66 | [ -n "${QOPTS[${ONAME}]}" ] &&
67 | CMD+=" ${ONAME}\"${OVAL}\"" || CMD+=" ${ONAME}"
68 |
69 | } || {
70 | CMD+=" \"${O}\""
71 |
72 | }
73 | }
74 |
75 | [ "${O}" = "-" ] && STDINSTDOUT=1 || true
76 | done
77 |
78 |
79 | [ -n "${STDINSTDOUT}" ] && {
80 | echo "Piping to/from STDIN/STDOUT. Cannot filter STDERR at this time."
81 | eval "${CMD}"
82 |
83 | } || {
84 | local STDERR=$( { eval "${CMD}"; } 2>&1 );
85 |
86 | for ERR in ${STDERR}; do
87 | [[ ! "${ERR}" =~ .*[Hh]eader\ [Kk]eyword\ [\"\']SCHILY.* ]] &&
88 | echo "${ERR}" || true
89 | done
90 |
91 | }
92 |
93 | } # END tar ()
94 |
95 | # vim: ft=sh
96 |
--------------------------------------------------------------------------------
/files/update_title_bar:
--------------------------------------------------------------------------------
1 | #-- update_title_bar
2 | # This is primarily intended for Linux systems, but will likely work for any modern BaSH version.
3 | #
4 | # Author: Jeremy Melanson
5 | #
6 | # Source-code, documentation and revision Git repository: https://github.com/zish/bashrc_enhancements
7 | #
8 | # Last-Modified: 2016-09-08
9 | #
10 | # $ git clone https://github.com/zish/bashrc_enhancements
11 | #
12 | # To use this, source the file from your .bashrc (or .bash_profile).
13 | #
14 | #
15 | # This file is part of bashrc_enhancements.
16 | #
17 | # bashrc_enhancements is free software: you can redistribute it and/or modify
18 | # it under the terms of the GNU Affero General Public License as published by
19 | # the Free Software Foundation, either version 3 of the License, or
20 | # (at your option) any later version.
21 | #
22 | # bashrc_enhancements is distributed in the hope that it will be useful,
23 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | # GNU Affero General Public License for more details.
26 | #
27 | # You should have received a copy of the GNU Affero General Public License
28 | # along with bashrc_enhancements. If not, see .
29 | #
30 |
31 | update_title_bar () {
32 | #--- Initialize the PROMPT_COMMAND and trap, if the first arg is "init".
33 | [[ "${1}" == "init" ]] && {
34 | [[ "${PROMPT_COMMAND}" != "" ]] && PROMPT_COMMAND+=";"
35 | PROMPT_COMMAND+='update_title_bar 0 ${SHELL}'
36 | trap 'update_title_bar ${0}' DEBUG
37 | #--- Set some text replacment defaults.
38 | [[ -z "${UTB_TEXT_REPLACE[*]}" ]] && {
39 | UTB_TEXT_REPLACE=(
40 | "${HOME}" '~'
41 | )
42 | }
43 | }
44 | local BCMD="${BASH_COMMAND}"
45 | #--- the trap command associated with this function passes ${0} as an argument.
46 | # If this valye exists, we should be able to assume that we are running in a
47 | # script (or during source'ing our bashrc file(s).
48 | # The idea is to skip any scripted or source'd commands.
49 | local IN_SCRIPT="${1}"
50 | local MANUAL_CMD="${2}"
51 | #--- Entering a second arg to this function overrides the output of the command name.
52 | [[ "${MANUAL_CMD}" != "" ]] && BCMD="${MANUAL_CMD}"
53 | local CMDRGX="${BCMD//\\/\\\\}"; CMDRGX="${CMDRGX//\//\\\/}"; CMDRGX="${CMDRGX//\$/\\\$}"
54 | CMDRGX="${CMDRGX//\{/\\\{}"; CMDRGX="${CMDRGX//\}/\\\}}"
55 | #--- Skip any commands that we've deemed to be "scripted".
56 | [[ "${IN_SCRIPT}" == "IN" ]] && {
57 | return
58 | #--- Skip any commands that exist in PROMPT_COMMAND
59 | # WARNING: Bear in mind that manually-entered commands that match are also ignored.
60 | } || [[ ! "${PROMPT_COMMAND}" =~ ${CMDRGX} ]] && {
61 | #--- If BCMD is trying to set the terminal title, we don't do anything.
62 | [[ ! "${BCMD}" =~ \\e\]0\; ]] && {
63 | local OUT=
64 | #--- Make the title more noticable, if running with root privileges.
65 | [[ ${EUID} == 0 ]] && OUT+="(ROOT_USER) " || OUT+="${USER}@"
66 | OUT+="${HOSTNAME}:"
67 | OUT+="${PWD} "
68 | OUT+="[${BCMD}]"
69 | local R=
70 | for ((E=0; E<${#UTB_TEXT_REPLACE[@]}; E+=2)); do
71 | local R="${UTB_TEXT_REPLACE[$E]}"
72 | local RGX="${R//\\/\\\\}"; RGX="${RGX//\//\\\/}"; RGX="${RGX//\$/\\\$}";
73 | RGX="${RGX//\{/\\\{}"; RGX="${RGX//\}/\\\}}"
74 | [[ "${OUT}" =~ ${RGX} ]] && {
75 | OUT="${OUT//${RGX}/${UTB_TEXT_REPLACE[$((${E}+1))]}}"
76 | }
77 | done
78 | echo -ne "\e]0;${OUT}\007"
79 | }
80 | }
81 | } # END _update_title_bar
82 |
83 | #--- Some stuff needs to be initialized, for things to work correctly.
84 | update_title_bar init
85 |
86 | # vim: ft=sh
87 |
--------------------------------------------------------------------------------
/files/command_not_found_handle:
--------------------------------------------------------------------------------
1 | #- Augment for command_not_found_handler function.
2 | # This tool digests a named array called COMMAND_TYPOS.
3 | # Its primary function is to intercept command typos, including those with spaces.
4 | # Because of this, it also creates the ability to define command aliases with spaces (eg. 'l s-l'='ls -l').
5 | #
6 | # Author: Jeremy Melanson
7 | #
8 | # Source-code, documentation and revision Git repository: https://github.com/zish/bashrc_enhancements
9 | #
10 | # Author: Jeremy Melanson
11 | #
12 | # Last-Modified: 2016-09-08
13 | #
14 | # $ git clone https://github.com/zish/bashrc_enhancements
15 | #
16 | # To use this, source the file from your .bashrc (or .bash_profile).
17 | #
18 | # This file is part of bashrc_enhancements.
19 | #
20 | # bashrc_enhancements is free software: you can redistribute it and/or modify
21 | # it under the terms of the GNU Affero General Public License as published by
22 | # the Free Software Foundation, either version 3 of the License, or
23 | # (at your option) any later version.
24 | #
25 | # bashrc_enhancements is distributed in the hope that it will be useful,
26 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | # GNU Affero General Public License for more details.
29 | #
30 | # You should have received a copy of the GNU Affero General Public License
31 | # along with bashrc_enhancements. If not, see .
32 |
33 | # TODO:
34 | # Document how to include and invoke all dependencies with SSH intercept.
35 | # Document examples, and manifesto.
36 | # Caveats:
37 | # Command must not exist to be used as an alias, including any cmd_alias with spaces (commands up to the first space).
38 | #
39 | # Figure out how to create aliases when needed (to help with the first caveat above).
40 | #
41 |
42 | [ -z "${COMMAND_TYPOS}" ] && declare -A COMMAND_TYPOS
43 |
44 | #- Rename the original "command_not_found_handle" function to "_system_command_not_found_handle".
45 | # If it is not defined, a small function is defined to take its place, to avoid complexity.
46 | # TODO: Create a mechanism for basic "fallback" or "alternative" commands, if functionality for a command does not exist.
47 | _rename_orig_command_not_found_handle () {
48 | local RGX="^([^\S=]+) \(\)"
49 | NEW="_system_command_not_found_handle () "
50 | local ORIG_FUNC_NAME="command_not_found_handle"
51 | #--- Avoid problems with new function, if it was already defined.
52 | local IFS=$'\n'
53 | [ "${_COMMAND_TYPOS_INIT}" = "1" ] && ORIG_FUNC_NAME="_system_command_not_found_handle"
54 |
55 | local OUTPUT=$(set | while read -r L; do
56 | [[ "${L}" =~ ${RGX} ]] && {
57 | [[ "${BASH_REMATCH[1]}" == ${ORIG_FUNC_NAME} ]] && {
58 | export FMATCH="1"
59 | }
60 | } || {
61 | [[ "${L}" =~ ^\}$ ]] && {
62 | #--- function was found and recorded. "eval" it with the new name.
63 | [ "${FMATCH}" = "1" ] && {
64 | echo -e "export _COMMAND_TYPOS_INIT=1;\n${NEW}\n}"
65 | return
66 | }
67 | } || {
68 | [ "${FMATCH}" = "1" ] && {
69 | export NEW="${NEW}${L}\n"
70 | }
71 | }
72 | }
73 | done)
74 |
75 | [ -n "${OUTPUT}" ] && echo -e "${OUTPUT}" \
76 | || echo -e "export _COMMAND_TYPOS_INIT=1;\n${NEW}{ echo -ne \"\"; }"
77 |
78 | echo -e 'command_not_found_handle () {
79 | local EXITLVL=
80 | local INPUT_CMD=(${@})
81 | local CHECK=
82 | local RUN_CMD=()
83 | for C in "${INPUT_CMD[@]}"; do
84 | [ -n "${RUN_CMD[0]}" ] && {
85 | RUN_CMD=(${RUN_CMD} ${C})
86 | } || {
87 | [ -z "${CHECK}" ] && CHECK="${C}" || CHECK="${CHECK} ${C}"
88 | [ -n "${COMMAND_TYPOS[${CHECK}]}" ] && {
89 | RUN_CMD=("${COMMAND_TYPOS[${CHECK}]}")
90 | }
91 | }
92 | done
93 | # TODO: Need to look at prior commands/functions/aliases for matching instances. Course through all (Makes this work much more like aliases)
94 | #echo "-------------------"
95 | #echo "INP: \"${INPUT_CMD[*]}\" \"${RUN_CMD[*]}\""
96 | #echo "-------------------"
97 | [ -n "${RUN_CMD}" ] && {
98 | ${RUN_CMD[*]}; EXITLVL=${?}
99 | #echo "-------------------"
100 | } || {
101 | eval "_system_command_not_found_handle ${INPUT_CMD[*]}; EXITLVL=${?}"
102 | }
103 | return ${EXITLVL}
104 | }'
105 | }
106 |
107 | eval "$(_rename_orig_command_not_found_handle)"
108 |
109 | # vim: ft=sh tabstop=3 expandtab
110 |
--------------------------------------------------------------------------------
/files/again:
--------------------------------------------------------------------------------
1 | # Author: Jeremy Melanson
2 | #
3 | # Changelog:
4 | # 2017-04-10 - JM : Initial pre-alpha, usable version created.
5 | #
6 | # TODO:
7 |
8 | #--- Useful little function that repeats a command each time a key is pressed.
9 | # The loop can be interacted with, using the following keystrokes:
10 | # 'a' - "all"; Run all commands remaining in the current loop iteration.
11 | # Re-prompt user after the final command.
12 | # 'h' - "help"; Display help text.
13 | # 'w' - "rewind"; Rewind to the command run before the most recent, and execute it.
14 | # 'n' - "next"; Run the 'next' command in the sequence. Restarts the loop if necessary.
15 | # 'p' - "previous"; Re-run the previous command in the sequence.
16 | # 'q' - Quit.
17 | # 'r' - Restart (Re-run the commands, starting from the first one).
18 | again () {
19 | local CMDS=("${@}")
20 | local IFS=$'\n'
21 | local PMSG="COMMAND ('h' for help)) -> "
22 | local HELP_MSG="USAGE:
23 | 'a': Run all remaining commands in list.
24 | 'p': Re-run 'p'revious command.
25 | 'h': Display this help text.
26 | 'n': Run next command in list
27 | 'q': Quit.
28 | 'r': restart from the beginning.\n
29 | 'w': Rewind and run the command before the last one."
30 | local SEPARATOR_LINE="---------------------------------------------------"
31 | local EXEC_DATA='
32 | echo -e "\n**** COMMAND ${CUR} (${CMDS[${CUR}]})\n";
33 | eval "${CMDS[${CUR}]}";'
34 |
35 | #--- Runs all remaining in the iteration, if nonzero.
36 | local DONE=
37 | local RUN_METHOD=
38 | local PREV_METHOD=
39 | while [ -z "${DONE}" ]; do
40 | local CUR=-1
41 | # If we are in run method 'N' (next), don't clear the value.
42 | # Clear it for every other one.
43 | [[ "${RUN_METHOD}" != "N" ]] && RUN_METHOD=
44 | while [ ${CUR} -lt ${#CMDS[@]} ]; do
45 | PREV_METHOD=${RUN_METHOD}
46 |
47 | # Only run the next command if the previous one wasn't 'unknown'.
48 | if [[ "${RUN_METHOD}" == "U" ]]; then
49 | RUN_METHOD=
50 | # Display help text, and revert to run method 'S'.
51 | elif [[ "${RUN_METHOD}" == "H" ]]; then
52 | echo -e "${SEPARATOR_LINE}\n${HELP_MSG}"
53 | RUN_METHOD=
54 | elif [[ "${RUN_METHOD}" != "" ]]; then
55 | if [[ "${RUN_METHOD}" == "A" ]]; then
56 | CUR=$((${CUR}+1))
57 | elif [[ "${RUN_METHOD}" == "P" ]]; then
58 | # if [[ "${RUN_METHOD}" == "P" ]]; then
59 | # CUR=$((${CUR}+1))
60 | RUN_METHOD=
61 | elif [[ "${RUN_METHOD}" == "W" ]]; then
62 | # CUR=$((${CUR}+1))
63 | RUN_METHOD=
64 | elif [[ "${RUN_METHOD}" == "N" ]]; then
65 | CUR=$((${CUR}+1))
66 | RUN_METHOD=
67 | fi
68 | eval "${EXEC_DATA}"
69 | fi
70 |
71 | if [[ ${CUR} -ge ${#CMDS[@]} ]]; then
72 | break
73 | fi
74 |
75 | # Only prompt the user for input if we're not in run method 'A'.
76 | [[ "${RUN_METHOD}" == "" ]] && {
77 | echo -e "${SEPARATOR_LINE}"
78 | read -p"${CUR} ${PMSG}" -n1 CHAR;
79 | case "${CHAR}" in
80 | a)
81 | RUN_METHOD=A
82 | echo -e " RUN ALL REMAINING"
83 | ;;
84 | h)
85 | RUN_METHOD=H
86 | echo -e "HELP"
87 | ;;
88 | w)
89 | local P=${CUR}
90 | # CUR=$((${CUR}-1))
91 | if [ ${CUR} -le 0 ]; then
92 | CUR=$((${#CMDS[@]}-1))
93 | # elif [ ${CUR} -lt 0 ]; then
94 | # CUR=$((${#CMDS[@]}-2))
95 | else
96 | CUR=$((${CUR}-1))
97 | fi
98 | if [ ${CUR} -lt 0 ]; then
99 | CUR=0
100 | fi
101 | RUN_METHOD=W
102 | echo -e " REWIND ${P} (${CUR})"
103 | ;;
104 | b|p)
105 | local P=${CUR}
106 | # [[ ${CUR} == 0 ]] && {
107 | # CUR=$((${#CMDS[@]}-1))
108 | # } || {
109 | # CUR=$((${CUR}-1))
110 | # }
111 | RUN_METHOD=P
112 | echo -e " PREVIOUS ${P} (${CUR})"
113 | ;;
114 | q)
115 | DONE=1
116 | echo -e " QUIT"
117 | break
118 | ;;
119 | r)
120 | echo -e " RESTART"
121 | break
122 | ;;
123 | n)
124 | local P=${CUR}
125 | # If the previous run method was W (rewind), we increment CUR.
126 | [[ "${PREV_METHOD}" == "W" ]] && CUR=$((${CUR}+1))
127 | RUN_METHOD=N
128 | echo -e " NEXT ${P} (${CUR})"
129 | ;;
130 | *)
131 | # Pressing space or enter should work the same as pressing 'n'.
132 | [[ "${CHAR}" =~ ^\ ?$ ]] && {
133 | local P=${CUR}
134 | RUN_METHOD=N
135 | echo -e " NEXT (${P})"
136 | } || {
137 | # u == unknown command
138 | RUN_METHOD=U
139 | echo -e " ***UNKNOWN***"
140 | }
141 | ;;
142 | esac
143 | }
144 | done
145 | done
146 | }
147 |
148 | # vim: ft=sh tabstop=3
149 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # bashrc\_enhancements
2 | Some useful functions, shortcuts, and enhancements to add to your \.bashrc \(or \.bash\_profile\)\.
3 |
4 | Current functions are called *addpath*, *sudo*, and *tar*\.
5 | *sudo* and *tar* are "intercept" functions, which are used to add functionality to existing commands of the same name\.
6 |
7 | ## addpath \- Keep your PATH clean\.
8 |
9 | This function will \(intelligently\) add a directory to your PATH, with conditions:
10 | 1. Item will only be added if it exists and is a directory \(Handy when you want to use the same .bashrc across dissimilar systems\)\.
11 | 2. If the item already exists in PATH, its location in PATH is changed or removed \(Useful if required to reference the same .bashrc from nested bash shells\)\.
12 |
13 | __Available options:__
14 | *The following arguments are optional:*
15 | * first \- Add the entry before all other entries in PATH\.
16 | * remove \- Remove any references to the entry from PATH\.
17 |
18 | * _If no options are specified, the entry is appended to the end of PATH\._
19 |
20 | ### Syntax examples:
21 | *SCENARIO:*
22 | * The original value of PAbring it with you to remote SSH sessions\.
23 | ```
24 | addpath /usr/bin first
25 | * _Value of PATH becomes "/usr/bin:/bin:/home/zish/bar"\._
26 | addpath /usr/local/sbin
27 | * _Value of PATH becomes "/usr/bin:/bin:/home/zish/bar:/usr/local/sbin"\._
28 | addpath /usr/local/sbin
29 | * _Value of PATH remains "/usr/bin:/bin:/home/zish/bar:/usr/local/sbin"\._
30 | addpath ${HOME}/bar remove
31 | * _Value of PATH becomes "/usr/bin:/bin:/usr/local/sbin"\._
32 | addpath ${HOME}/foo first
33 | * _If "${HOME}/foo" exists, PATH becomes "/usr/bin:/bin:/usr/local/sbin:/home/zish/foo"\._
34 | * _If "${HOME}/foo" does not exist, PATH remains "/usr/bin:/bin:/usr/local/sbin"\._
35 | ```
36 |
37 | ## ssh \- SSH interception subroutine with a lot of great extras\.
38 |
39 | This was written originally as a mechanism to bring my locally\-defined PS1 prompt and bash aliases with me, so I didn't need to copy them everywhere\. It has since had a lot more functionality added to it\.
40 |
41 | ### Features:
42 | * Define PS1 locally, and have it appear in remote SSH sessions\.
43 | * Use locally\-defined aliases in remote SSH sessions\.
44 | * Use locally\-defined subroutines in remote SSH sessions \(must be explicity defined\)\.
45 | * Arbitrarily add sections from your local bashrc as needed\.
46 | * Automaticallly log output from SSH sessions\.
47 | * _Ability to override these options for hosts\._
48 | ..* _Overrides are specified as a comment at the end of a 'Host' line that matches the host, in your ~/\.ssh/config file\._
49 |
50 | ### See README\.ssh\.md file for configuration and usage\.
51 |
52 |
53 | ## sudo \- SUDO interception command\. This allows you to use available aliases with the sudo command\.
54 |
55 | This will intercept the "sudo" command\. If the command executed by sudo matches a defined alias, it will execute the contents of the alias instead\.
56 |
57 | ### Examples:
58 |
59 | _In \.bashrc:_
60 |
61 | alias tlog='tail \-100 /var/log/syslog'
62 |
63 | Normally this alias would need to be defined in root's \.bashrc file to be used\. Even still, there may be security controls restricting what may be available from a sudo command, or tools that manage the integrity of root\'s \.bashrc entirely\. Thus running "sudo tlog" would fail with a "command not found" error\.
64 |
65 | The sudo intercept function instead will rewrite the sudo command appropriately\. The command "sudo tlog" gets invoked as "sudo tail \-100 /var/log/syslog"\.
66 |
67 |
68 | ## tar \- Tar interception command\. Suppresses annoying "SCHILY" messages when extracting a TAR archive originating from a MacOS system\.
69 |
70 | This is primarily intended for Linux systems, but can be used for any system with GNU/Tar\.
71 | This cuts down the amount of output echoed to your terminal or output log,
72 | and is expecially useful when extracting a tar file from MacOS with a lot of files\.
73 |
74 |
75 | ## Installation:
76 |
77 | *Simple method:*
78 |
79 | Copy the contents of this repo to \$\{HOME\}/\.bashrc\_enhancements
80 | Add the text "\. \$\{HOME\}/\.bashrc\_enhancements/bashrc" on a blank line in your \.bashrc \(or \.bash\_profile\)
81 | near the beginning of the file\.
82 |
83 |
84 | *Portable method:*
85 |
86 | The simple method requires that \$\{HOME\}/\.bashrc\_enhancements be made available on any system that you
87 | wish to use it on\. As an alternative, the contents of any file under \$\{HOME\}/\.bashrc\_enhancements/files
88 | can be added directly to your \.bashrc file\.
89 |
90 |
91 | ## License:
92 |
93 | _bashrc\_enhancements_ is free software: you can redistribute it and/or modify
94 | it under the terms of the GNU Affero General Public License as published by
95 | the Free Software Foundation, either version 3 of the License, or
96 | \(at your option\) any later version\.
97 |
98 | _bashrc\_enhancements_ is distributed in the hope that it will be useful,
99 | but WITHOUT ANY WARRANTY; without even the implied warranty of
100 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE\. See the
101 | GNU Affero General Public License for more details\.
102 |
103 | A copy of the GNU Affero General Public License should be provided along
104 | with _bashrc\_enhancements_\. If not, see \.
105 |
106 |
--------------------------------------------------------------------------------
/files/addpath:
--------------------------------------------------------------------------------
1 | #-- Add a directory to PATH, but make sure it exists.
2 | # - If it already exists, change location or remove it. Repeated entries are condensed as well.
3 | #
4 | # Author: Jeremy Melanson
5 | #
6 | # Source-code, documentation and revision Git repository: https://github.com/zish/bashrc_enhancements
7 | #
8 | # Last-Modified: 2016-09-08
9 | #
10 | # $ git clone https://github.com/zish/bashrc_enhancements
11 | #
12 | # To use this, source the file from your .bashrc (or .bash_profile).
13 | #
14 | #-- Syntax examples:
15 | # "addpath /usr/bin first" - Adds "/usr/bin" to the beginning of PATH.
16 | # "addpath /usr/local/sbin" - Adds "/usr/local/sbin" to the end of PATH.
17 | # "addpath /usr/local/sbin" - Repeat of the previous to illustrate that
18 | # duplicates do not get added.
19 | # "addpath ${HOME}/foo first" - Adds "foo" from your home directory
20 | # Ex. "/home/zish/foo") to the beginning
21 | # of PATH.
22 | # "addpath ${HOME}/bar remove" - Removes any references to "${HOME}/bar"
23 | # Ex. "/home/zish/foo") from PATH.
24 | #
25 | #-- Results:
26 | # - If the original value of PATH was "/bin:/usr/bin:/home/zish/bar"...
27 | # ... and "/home/zish/foo" exists, the end result would be
28 | # "/home/zish/foo:/bin:/usr/bin:/usr/local/sbin".
29 | # ... and "/home/zish/foo" does not exist, the end result would be
30 | # "/bin:/usr/bin:/usr/local/sbin".
31 | #
32 | #
33 | # This file is part of bashrc_enhancements.
34 | #
35 | # bashrc_enhancements is free software: you can redistribute it and/or
36 | # modify it under the terms of the GNU Affero General Public License as
37 | # published by the Free Software Foundation, either version 3 of the License,
38 | # or (at your option) any later version.
39 | #
40 | # bashrc_enhancements is distributed in the hope that it will be useful,
41 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
42 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43 | # GNU Affero General Public License for more details.
44 | #
45 | # You should have received a copy of the GNU Affero General Public License
46 | # along with bashrc_enhancements. If not, see .
47 |
48 | addpath () {
49 | #-- Enable the use of embedded regular expressions (if not already set)
50 | shopt -s extglob
51 |
52 | local NEW=${1}
53 | local PPOS=;
54 | [[ ${2} ]] && PPOS=${2}
55 | #-- Add a little verbosity if this is nonzero.
56 | # Useful for debugging things, if needed.
57 | local VERB=${3}
58 |
59 | #-- These are a couple helper functions to support addpath.
60 | __addpath_verb () { [[ ${VERB} ]] && echo "-- ${1}"; }
61 | __addpath_join () { local IFS="${AP_VAR_DELIM}"; echo "${*}"; }
62 | __addpath_clean () { local IFS="${AP_VAR_DELIM}"; echo "${*}"; }
63 |
64 | #-- Default variable to act against is 'PATH'.
65 | [ -z "${AP_VAR_NAME}" ] && AP_VAR_NAME="PATH"
66 | #-- Default delimiter is ':'.
67 | [ -z "${AP_VAR_DELIM}" ] && AP_VAR_DELIM=":"
68 |
69 | #-- We can't use associative arrays (hashes) in BaSH versions < 4.x).
70 | (( "${BASH_VERSINFO}" >= 4 )) && {
71 | #-- Read PATH into an associative array (automatically removes duplicates).
72 | declare -A CPATHS
73 | local OI="${IFS}"; local IFS="${AP_VAR_DELIM}"; local C=0
74 | eval "for P in \${${AP_VAR_NAME}}; do \
75 | CPATHS[\${P}]=\${C}; C=\$((\${C} + 1)); done"
76 | local IFS="${OI}"
77 | } || {
78 | #-- We get here if BaSH version < 4.
79 | __addpath_verb "Warning: Using an old BaSH version (${BASH_VERSINFO}). "
80 | __addpath_verb "Some features are disabled."
81 | if [ "${PPOS}" = "first" ]; then
82 | eval "${AP_VAR_NAME}=\"${NEW}${AP_VAR_DELIM}$(eval "echo \${${AP_VAR_NAME}}")\""
83 | __addpath_verb "Added ${NEW} to beginning of ${AP_VAR_NAME}"
84 | elif [ "${PPOS}" = "remove" ]; then
85 | __addpath_verb "Running old BaSH version. Skipping removal of '${NEW}'."
86 | else
87 | eval "${AP_VAR_NAME}=\"$(eval "echo \${${AP_VAR_NAME}}")${AP_VAR_DELIM}${NEW}\""
88 | __addpath_verb "Added ${NEW} to end of ${AP_VAR_NAME}"
89 | fi
90 | export ${AP_VAR_NAME}
91 | unset AP_VAR_NAME; return
92 | }
93 |
94 | #-- Remove trailing '/', if it exists.
95 | [[ "${NEW}" =~ (.+)\/$ ]] && NEW="${BASH_REMATCH[1]}"
96 | #-- Make sure the directory exists, and that it wasn't
97 | # already added to PATH.
98 | [ ! -d ${NEW} ] && {
99 | __addpath_verb "${NEW} does not exist or is not a directory"
100 | if [ "${PPOS}" = "remove" ]; then
101 | __addpath_verb "Removal of ${NEW} requested. Continuing with task."
102 | else
103 | unset AP_VAR_NAME; return
104 | fi
105 | }
106 |
107 | local PATHDIRS=()
108 | for P in "${!CPATHS[@]}"; do
109 | local POS="${CPATHS[${P}]}"
110 | if [ "${P}" = "${NEW}" ]; then
111 | __addpath_verb "${NEW} already in ${AP_VAR_NAME}."
112 | if [ "${PPOS}" = "remove" ]; then
113 | __addpath_verb "Removal of ${NEW} requested. Continuing with task."
114 | else
115 | __addpath_verb "Not continuing."
116 | unset AP_VAR_NAME; return
117 | fi
118 | else
119 | PATHDIRS[${POS}]="${P}"
120 | fi
121 | done
122 |
123 | if [ "${PPOS}" = "first" ]; then
124 | PATHDIRS=(${NEW} ${PATHDIRS[@]})
125 | eval "${AP_VAR_NAME}=\"$(__addpath_join ${PATHDIRS[@]})\""
126 | __addpath_verb "Added ${NEW} to beginning of ${AP_VAR_NAME}"
127 | elif [ "${PPOS}" = "remove" ]; then
128 | __addpath_verb "Removal of ${NEW} requested. Not re-adding to ${AP_VAR_NAME}."
129 | eval "${AP_VAR_NAME}=\"$(__addpath_join ${PATHDIRS[@]})\""
130 | else
131 | PATHDIRS=(${PATHDIRS[@]} ${NEW})
132 | eval "${AP_VAR_NAME}=\"$(__addpath_join ${PATHDIRS[@]})\""
133 | __addpath_verb "Added ${NEW} to end of ${AP_VAR_NAME}"
134 | fi
135 | export ${AP_VAR_NAME}
136 | unset AP_VAR_NAME
137 | }
138 |
139 | # vim: tabstop=2 expandtab filetype=sh
140 |
--------------------------------------------------------------------------------
/README.ssh.md:
--------------------------------------------------------------------------------
1 | # SSH Intercept function README
2 |
3 | This was written originally as a mechanism to bring my locally\-defined PS1 prompt and bash aliases with me, so I didn't need to copy them everywhere\. It has since had a lot more functionality added to it\.
4 |
5 | ### Features:
6 | * Define PS1 locally, and have it appear in remote SSH sessions\.
7 | * Use locally\-defined aliases in remote SSH sessions\.
8 | * Use locally\-defined subroutines in remote SSH sessions \(must be explicity defined\)\.
9 | * Automaticallly log output from SSH sessions\.
10 | * Arbitrarily add sections of your local bashrc\.
11 | * _Ability to override these options for hosts\._
12 | * _Overrides are specified as a comment at the end of a 'Host' line that matches the host, in your ~/\.ssh/config file\._
13 |
14 | ## Configuration Environment variables for ssh intercept function\.
15 | *Defining these variables in your \.bashrc will override the default\.*
16 |
17 | ### SSHI\_ADD\_SUBS \- Specifies what locally\-defined functions to include in a remote SSH session\.
18 | The value should be a comma-separated list.
19 | _Default:_
20 | * SSHI\_ADD\_SUBS="sudo, ssh, tar, addpath"
21 |
22 | ### SSHI\_BASH\_RCFILES \- Specifies a list of "rc" files to read for [SSHI\INCLUDE] entries.
23 | The value should be a comma-separated list.
24 | _Default:_
25 | SSHI\_BASH\_RCFILES="${HOME}/.bashrc, ${HOME}/.bash\_profile, ${HOME}/.profile"
26 |
27 | _The files in the list are read in the order they are listed._
28 |
29 | ### SSHI\_RPS1 \- Remote PS1 Prompt\.
30 | The default prepends the local PS1 with a red, bold SSH between parentheses\. This identifies, at a glance, that the terminal window is an SSH session\.
31 | _Default:_
32 | * SSHI\_RPS1='\\\[\\033\[1;1m\\\]\(\\\[\\033\[1;31m\\\]SSH\\\[\\033\[0;1m\\\]\)\\\[\\033\[0;37m\\\]$\{PS1\}'
33 | To remotely use your local PS1 unmodified, use the following:
34 | * SSHI\_RPS1=$\{PS1\}
35 |
36 | ### SSHI\_SSH\_UC \- SSH Local user config file
37 | _Default:_
38 | * SSHI\_SSH\_UC=$\{HOME\}/\.ssh/config
39 |
40 | ### SSHI\_SSH\_MC \- SSH system\-wide \(main\) config file
41 | _Default:_
42 | * UNDEFINED
43 |
44 | _Omitting SSHI\_MC \(main cnf\) avoids the need to override "host \*" in the user config, so you will probably not need to use it\._
45 |
46 | ### SSHI\_LOG\_BY\_DEF \- Enable local logging of SSH sessions by default\.
47 | _Default:_
48 | * SSHI\_LOG\_BY\_DEF=1
49 |
50 | Setting this to 0 or undefined will cause the function to skip local logging, unless the LOG option is matched to a Host in the ssh config file\(s\)\.
51 |
52 | ### SSHI\_LOG\_LOC \- SSH local session log destination directory\.
53 | _Default:_
54 | * SSHI\_LOG\_LOC=~/ssh\_logs
55 |
56 | *The directory specified must exist for logging to occur\.*
57 |
58 | _Log file names in this directory will be formatted as 'HOST\-YYYY\-MM\-DD_HH\-MM\-SS\.log'\._
59 |
60 | ### SSHI\_CREATE\_LOG\_LOC \- Create the log destination dir, if it doesn't exist\.
61 | _Default:_
62 | * SSHI\_CREATE\_LOG\_LOC=1
63 |
64 | If SSHI\_CREATE\_LOG\_LOC is nonzero, the log destination directory \(SSHI\_LOG\_LOC) will be created if it does not exist\.
65 |
66 | ### SSHI\_NO\_LOG\_REMOTE \- Don't try to generate logs, when using ssh function in a remote SSH session\.
67 | _Default:_
68 | * SSHI\_NO\_LOG\_REMOTE=1
69 |
70 | *No logging functions will be attempted, if SSHI\_NO\_LOG\_REMOTE is nonzero\.*
71 |
72 | SSHI\_LOG\_COMPRESS \- Compress SSH logs\.
73 | _Default:_
74 | * SSHI\_LOG\_COMPRESS=1
75 |
76 | *If SSHI\_LOG\_COMPRESS is nonzero, any SSH logs older than SSHI\_LOG\_CMP\_AGE will be compressed\.*
77 |
78 | SSHI\_LOG\_CMP\_BIN \- SSH log compression tool to use\.
79 | _Default:_
80 | * SSHI\_LOG\_CMP\_BIN=gzip
81 |
82 | *The compresion tool specified by SSHI\_LOG\_CMP\_BIN must support reading from STDIN, and writing to STDOUT\.*
83 |
84 | SSHI\_LOG\_CMP\_OPTS \- Command\-line options for compression tool \(specified by SSHI\_LOG\_CMP\_BIN)\.
85 | _Default:_
86 | * SSHI\_LOG\_CMP\_OPTS=-9
87 |
88 | SSHI\_LOG\_CMP\_AGE \- Set the minimum SSH log age \(in days) for compression eligibility\.
89 | _Default:_
90 | * SSHI\_LOG\_CMP\_AGE=3
91 |
92 | SSHI\_LOG\_MIN\_SIZE \- Minimum size \(in bytes) an SSH log must be to avoid being deleted\.
93 | _Default:_
94 | * SSHI\_LOG\_MIN\_SIZE=512
95 |
96 | *When performing SSH log directory maintenance, delete old logs \(see SSHI\_LOG\_CMP\_AGE) that are smaller than SSHI\_LOG\_MIN\_SIZE\.*
97 |
98 | ### SSHI\_SSH\_BIN \- Location of SSH command\.
99 | _Default:_
100 | * SSHI\_SSH\_BIN=/usr/bin/ssh
101 |
102 | *If the SSH command is in a different location, it can be defined using this option\.*
103 |
104 | ### SSHI\_DBG \- "Debug" level for performing debug tasks.
105 | _Default:_
106 | * SSHI\_DBG=4
107 |
108 | *A file must be specified in SSHI\_DBG\_DST to enable debugging output.*
109 |
110 | ### SSHI\_DBG\_DST \- Destination file for debugging output.
111 | _Default:_
112 | * UNDEFINED
113 |
114 | ## Using \[SSHI\_INCLUDE\] in your local bashrc\.
115 | *This gives you the ability to include parts of your bashrc that otherwise wouldn't be easily transferrable\.*
116 | If, for example, an external tool or function required commented lines or encoded data from your local bashrc, these could be made available to the user on the remote system\.
117 | This can also be used to include local environment variables on the remote system, but their definitions must be in the local \.bashrc\.
118 |
119 | To include lines from your bashrc, add "\# \[SSHI\_INCLUDE\] XX" \(where XX is the number of lines\) to the line above the section you want\.
120 |
121 | ### Examples:
122 |
123 | Export the local EDITOR env variable on the remote system\.
124 | ```
125 | # [SSHI_INCLUDE] 1
126 | export EDITOR='vim'
127 | ```
128 |
129 | Use 'addpath' function on remote session to manage PATH\.
130 | ```
131 | # [SSHI_INCLUDE] 6
132 | #-- Android Dev Stuff...
133 | addpath ${HOME}/bin/android-studio/bin first
134 | addpath ${HOME}/bin/android-studio/sdk/tools first
135 | addpath ${HOME}/bin/android-studio/sdk/platform-tools first
136 | addpath ${HOME}/bin/android-studio/sdk/build-tools/android-4.4.2 first
137 | export ANDROID_HOME=${HOME}/bin/android-studio/sdk
138 | ```
139 |
140 | *Lines marked by "\[SSHI\_INCLUDE\] XX" are made available in the "\.bashrc\_pushed\-\[user\]\.funcs" file on the remote system\.*
141 |
142 |
143 | ## Overriding settings for hosts in the SSH config file\.
144 |
145 | _NOTE:_ To make use of the majority of features in the SSH intercept function, a remote SSH Host **_Must_** have a matching Host entry in the SSH config\. *Session logging does not require a matching Host entry, if SSHI\_LOG\_BY\_DEF is set\.*
146 |
147 | ### SSH config host entry examples:
148 | *SSH intercept function only needs a "Host" line\. Additional SSH Host options are ignored by the function itself\.*
149 |
150 | *Host 10\.20\.30\.40 www\.cefncefh\.com*
151 | * SSH sessions to IP address 10\.20\.30\.40 and Hostname www\.cefncefh\.com will include local PS1, available functions, aliases\. Sessions will be logged if SSHI\_LOG\_BY\_DEF is set\.
152 |
153 | *Host internal\-\*\.jakakwpqs\.net 192\.168\.\*\.\**
154 | * This illustrates that wildcards are supported\.
155 |
156 | *Host argle\.bargle\.systemhalted\.com \#PROMPTONLY*
157 | * Only use the PS1 prompt on the remote host\. Local aliases and functions will not be included\.
158 |
159 | *Host foo\.csopqcnaleicn\.lan \#NOLOG,PROMPTONLY*
160 | * Only use the PS1 prompt on the remote host\. Local aliases and functions will not be included\.
161 | * Disable logging if SSHI\_LOG\_BY\_DEF is set\.
162 |
163 | *Host bar\.csopqcnaleicn\.lan \# PROMPTONLY, LOG*
164 | _This illustrates multiple options can be used per host entry\._
165 | * Only use the PS1 prompt on the remote host\. Local aliases and functions will not be included\.
166 | * Enable logging if SSHI\_LOG\_BY\_DEF is NOT set\.
167 |
168 | *Host firewall\.internal\-network\.lan \#NOPROMPT*
169 | *Host \*\.internal\-network\.lan*
170 | * Disable use of local PS1, available functions, aliases for host firewall\.internal\-network\.lan\.
171 | * \.\.\.but enable for all other hosts matching \*\.internal\-network\.lan\.
172 |
173 | ### Roadmap:
174 | * Get remote file shipping to work.
175 | 1a. Just copy the files for now\. Do not copy if the files are pre\-existing\.
176 | 1b. Eventually checksum both files, and copy if the contents differ\.
177 |
178 | * Additional functionality in file shipping:
179 | 2. Generate checksums of each file to be included\.
180 | * Store these checksums on the remote host\. use them to compare local and remote copies\.
181 | * Only copy each file, if it either does not exist, or the checksums don't match\.
182 | 3. New option "SSHI\_INC\_FILES\_ARCHIVE\_LOC"
183 | * Used when including local files to the remote host\. This specifies a location to archive pre\-existing remote files, before they are replaced by the local version\. This functionality is disabled if SSHI\_INC\_FILES\_ARCHIVE\_LOC is not set, or the matching host entry in the SSH config includes the "NO\_ARCHIVE\_REMOTE\_FILES" option\.
184 | 4. Add per\-host override for SSHI\_INC\_FILES, allowing the ability to specify different files per\-host\.
185 |
186 | ### Additional techinical details:
187 |
188 | ## Variable names and their function:
189 | R\_O \- Returned output from last command iteration executed by \_sshi\_retry\_task\.
190 | RCPUSH \- Defines the name of the pushed \.bashrc file \(\.bashrc\_pushed\-\[username\]\)\.
191 | S\_A \- Holder for aliases to be packaged and included in remote SSH session\.
192 | S\_BD \- Holds Perl BASE64 decoder script\.
193 | S\_BE \- Holds Perl BASE64 encoder script\.
194 | S\_E \- Used as boolean. Set as true when trying to determine if the session log can be written to\.
195 | S\_F \- Set by \_sshi\_scancnf function when an SSH Host entry was matched in the SSH config\(s\)\.
196 | S\_LFM \- Defines the name format of the session's log file\.
197 | S\_LF \- Defines the full path of the session log file\.
198 | S\_LG \- Used as boolean. Set by \_sshi\_scancnf, when the SSH config host entry has the "LOG" option defined\.
199 | S\_NL \- Used as boolean. Set by \_sshi\_scancnf, when the SSH config host entry has the "NOLOG" option defined\.
200 | SSHREMCMD \- Holder for the commands to run on the remote SSH session, in order to set up the environment\.
201 | SSHEXEC \- Full SSH command to execute, including contents of S\_SC\.
202 | SSHI\_IS\_SSH \- Used as boolean\. This is an environment variable set in SSH session, to help determine if we are actively in an SSH session\.
203 |
204 |
205 |
--------------------------------------------------------------------------------
/files/ssh:
--------------------------------------------------------------------------------
1 | #- SSH interception subroutine with a lot great extras.
2 | # This was written originally to eliminate the need to copy or clone a custom
3 | # .bashrc to remote systems,
4 | #
5 | # Author: Jeremy Melanson
6 | # Last-Modified: 2016-09-08
7 | #
8 | # Source-code, documentation and revision Git repository:
9 | # https://github.com/zish/bashrc_enhancements
10 | #
11 | # $ git clone https://github.com/zish/bashrc_enhancements
12 | #
13 | # To use this, source the file from your .bashrc (or .bash_profile).
14 | #
15 | #
16 | # Features:
17 | # * Allows you to take your PS1 prompt with you.
18 | # - Prepends the remote prompt with "(SSH)", to visually indicate that it
19 | # is an SSH session.
20 | # * Any aliases defined locally at run time will be defined in your remote
21 | # session automatically.
22 | # * Select embedded functions can be cloned to your remote SSH session,
23 | # by adding them to SSHI_ADD_SUBS, (defined below),
24 | # * Specific ranges of ines in your .bashrc can be cloned to your remote
25 | # SSH session, using a special '# [SSHI_INCLUDE nn]' remark before the
26 | # lines without needing to copy them everywhere.
27 | #
28 | #
29 | # This file is part of bashrc_enhancements.
30 | #
31 | # bashrc_enhancements is free software: you can redistribute it and/or modify
32 | # it under the terms of the GNU Affero General Public License as published by
33 | # the Free Software Foundation, either version 3 of the License, or
34 | # (at your option) any later version.
35 | #
36 | # bashrc_enhancements is distributed in the hope that it will be useful,
37 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
38 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 | # GNU Affero General Public License for more details.
40 | #
41 | # You should have received a copy of the GNU Affero General Public License
42 | # along with bashrc_enhancements. If not, see .
43 | #
44 | # TODO: Retroactive log file scrubbing, based on Perl REGEX.
45 | # This is to provide the ability to store the SSH logs in a
46 | # less-restricted manner.
47 | #
48 | # Some ideas for scrubbing filters:
49 | # - Credit cards
50 | # - Mask Cisco pre-shared-keys, passwords, secrets
51 | # - Remove existing and old passwords (as provided) from files.
52 | # This requires hashing of files, and persistent storage, to
53 | # enhance performance and remove the need to repeat files.
54 | #
55 |
56 |
57 | #-- The '__sshi_l' alias is similar to 'tee', but is an embedded perl script.
58 | # This allows for log output filtering (TODO), and keeps external tool
59 | # dependencies to a minimum.
60 | #
61 | # ** SSHI WILL NOT USE THIS IF THE PROVIDED PERL VERSION IS < 5.18. **
62 | # ** IT WILL INSTEAD FALL BACK TO USING 'tail -i', WHICH DOES NOT PROVIDE **
63 | # ** FILTERING CAPABILITIES.
64 | #
65 | # __ COMMENTS have been moved from embedded Perl, and replaced with pointers.__
66 | # __ This is to decrease the in-memory size of the ssh intercept function. __
67 | # __ Bash Comments are omitted from in-memory, but embedded strings __
68 | # __ are left alone. __
69 | #
70 | # (1)- : \$mb == Maximum size of each buffer before filtering and flushing
71 | # to log file.
72 | # If you use a filter that requires a fairly long sample of
73 | # characters, you may need to increase this number. Use this guide:
74 | # 1. Roughly estimate the maximum bytes needed to apply the filter.
75 | # Rounding up is recommended.
76 | # 2. Multiply this number by 3.
77 | # 3. Modify \$mb=XXXX declaration in the alias to reflect
78 | # this number.
79 | # ** This alias uses 2 capture buffers, and runs filters against both,
80 | # ** then halfway between them.
81 | # (2)- : \$b == Which data capture buffer to fill.
82 | # (3)- : @b == Data capture 'b'uffers. We flip between them to facilitate log
83 | # filtering.
84 | # (4)- : \$o == 'o'verflow capture. This is for facilitating filtering.
85 | # We don't want text cut between buffers.
86 | # (2)- : \$l == Output 'l'og filehandle.
87 | # (2)- : \$c == Holder for each 'c'haracter captured.
88 | alias __sshi_l="perl -MIO::Handle -e '# This is a required component for the SSH Bash Intercept function.
89 | # part of the bashrc_enhancements project.
90 | my(\$b,\$mb,\$l,\$c,\$o)=(1,1000);my@b=(\"\");
91 | exit(1)if(!\$ARGV[0]);\$SIG{INT}=\"IGNORE\";
92 | if(open(\$l,\">\",\$ARGV[0])){\$l->autoflush(1);STDOUT->autoflush(1);
93 | while(!eof(STDIN)){\$c=getc(STDIN);print \$c;
94 | if((length(\$b[1])>=\$mb)||(\$c eq \"\\r\"||\$c eq \"\\n\")){out();}\$b[1].=\$c;}
95 | close(\$l);}
96 | else{die(\"Problem writing to \\\"\".\$ARGV[0].\"\\\":\".\$!.\"\\n\");}
97 | sub out{if((length(\$b[1])>=\$mb)||(\$c eq \"\\r\"||\$c eq \"\\n\")){print \$l \$b[1];\$b[1]=undef;}}' --"
98 |
99 | #-- Modification of anything within this section requires you
100 | # to reread your rc or restart bash.
101 | ssh () {
102 |
103 | #-- Debugging output subroutine. Only logs output when SSHI_DBG > MSG_LVL.
104 | _sshi_debug () {
105 | local MSG_LVL="${1}"
106 | local MSG="${2}"
107 | #- Skip debugging output when the destination file is undefined.
108 | [ -n "${SSHI_DBG_DST}" ] && return
109 | #- Skip debugging output when the message debug level is less than SSHI_DBG.
110 | [ ${SSHI_DBG} -lt ${MSG_LVL} ] && return
111 |
112 | echo -e "${MSG}" >> "${SSHI_DBG_DST}"
113 | }
114 |
115 | #-- Subroutine to set the configuration defaults, if no global overrides
116 | # have been set.
117 | #
118 | # ** DO NOT MODIFY THESE DIRECTLY. THEY **
119 | # ** SHOULD BE DEFINED IN YOUR LOCAL bashrc. **
120 | _sshi_defaults () {
121 | local IFS=$'\n'
122 | while read -r L; do
123 | [[ "${L}" =~ ^[[:blank:]]*\# ]] && continue #- Skip comment lines.
124 | [[ "${L}" =~ ^[[:blank:]]*([^\ \t\=]+)[[:blank:]]*\=[[:blank:]]*(.*) ]] && {
125 | echo "[ -z \"\${${BASH_REMATCH[1]}}\" ]&&local ${BASH_REMATCH[1]}=${BASH_REMATCH[2]}"
126 | }
127 | done<){ #(3)-
204 | $p=$_;
205 | %rt=("\\."=>"\\.","\\*"=>".*","\\?"=>"."); #(4)-
206 | if($p=~/^\s*host\s+([^\#]+)\#?([^\#]*)/i){ #(5)-
207 | $ch=$1;$a=$2;@h=($ch=~/([^\s\,]+)/g);
208 | foreach $H(@h){
209 | foreach $e(sort{$b cmp $a}(keys(%rt))){$H=~s/$e/$rt{$e}/g;} #(6)-
210 | $H="^($H)\$";
211 | if($sh=~/$H/){@O=split(/\s*\,\s*/,$a);o("S_F=$sh");
212 | o("S_LG=1","LOGFILE",\@O);
213 | o("S_NL=1","NOLOG",\@O);
214 | o("NOPROMPT=1","NOPROMPT",\@O);
215 | o("PROMPTONLY=1","PROMPTONLY",\@O);
216 | exit;
217 | }}}}' -- ${OP[@]}
218 | }
219 |
220 | #-- Clean the SSH Logs dir.
221 | # Removes .log files smaller than ${SSHI_LOG_MIN_SIZE} and compress .log files
222 | # older than ${SSHI_LOG_CMP_AGE}.
223 | _sshi_clean_log_dir () {
224 | local IFS=$'\n'
225 | local CT="$(date +'%s')"
226 | [ -z "${SSHI_LOG_COMPRESS}" ] && {
227 | return
228 | }
229 | [ ${SSHI_LOG_COMPRESS} -le 0 ] && {
230 | return
231 | }
232 | [ -z "${SSHI_LOG_CMP_AGE}" ] && {
233 | echo "SSHI_LOG_COMPRESS set, but age undefined. Cannot compress old logs."
234 | return
235 | }
236 | local F=
237 | #- TODO: Replace find/grep with native Bash or embedded Perl.
238 | for F in $(find ${SSHI_LOG_LOC} -maxdepth 1 -printf "%Cs %s %p\n"|grep -e "\.log$"); do
239 | [[ "${F}" =~ ^([0-9]+)\ ([0-9]+)\ (.*) ]] && {
240 | local D="$(((${CT}-${BASH_REMATCH[1]})/86400))"
241 | local S="${BASH_REMATCH[2]}"
242 | local L="${BASH_REMATCH[3]}"
243 | }
244 | [ ${D} -ge ${SSHI_LOG_CMP_AGE} ] && {
245 | [ ${S} -lt ${SSHI_LOG_MIN_SIZE} ] && {
246 | echo "Removing ${L} (Size is ${S} bytes. Minimum size is ${SSHI_LOG_MIN_SIZE})."
247 | eval "$(_sshi_retry_task 2 2 rm -f ${L})"
248 | } || {
249 | echo "Compressing ${L}"
250 | eval "$(_sshi_retry_task ${SSHI_LOG_CMP_BIN} ${SSHI_LOG_CMP_OPTS} ${L})"
251 | }
252 | }
253 | done
254 | }
255 |
256 | #-- Pull requested functions defined by SSHI_ADD_SUBS.
257 | # and lines in rc file marked by [SSHI_INCLUDE XX] remarks.
258 | # -(1)- : If there are any commas in the subroutine input list, we parse it
259 | # as a comma-separated list. Otherwise, we parse is as if it were
260 | # space-separated.
261 | # -(2)- : $b stands for {b}rackets.
262 | # -(3)- : Grab [SSHI_INCLUDE] sections in bashrc.
263 | # * GETS BOTH SSH_INCLUDE AND SSHI_INCLUDE.
264 | # SSH_INCLUDE will be deprecated in the near future.
265 | _sshi_getrc () {
266 | set | /usr/bin/perl -e '
267 | @rc=split(/\s*,\s*/,shift(@ARGV));
268 | my %addSubs;my $subsIn;my @subsIn;
269 | if($subsIn=~/,/){ #-(1)-
270 | @subsIn=split(/\s*\,\s*/,$ARGV[0]);
271 | }else{
272 | @subsIn=split(/\s*/,$ARGV[0]);
273 | }
274 | foreach my $f(split(/\s*,\s*/,shift(@ARGV))){
275 | $f=~s/^\s*\"?//;$f=~s/\"?\s*$//;
276 | $addSubs{$f}=1;
277 | }
278 | my $b;
279 | foreach my $l(){
280 | if($l=~/^\s*(\S+)\s+\([^\(\)]*\)\s*$/){$b=$1;} #-(2)-
281 | print $l if($addSubs{$b});
282 | $b=undef if($l=~/^\}\s*([\;\#]?.*)/);
283 | }
284 | foreach my $rcf(@rc) {
285 | $rcf=~s/^\s*\"?//;$rcf=~s/\"?\s*$//;
286 | if(!open(my $f,"<",$rcf)) {
287 | print STDERR "Cannot open rc file $rcf: $!\n";
288 | next;
289 | }else{
290 | my ($i,$c,$incPos);
291 | foreach my $l(<$f>){ #-(3)-
292 | if($l=~/^\s*\#\s*\[SSHI?_INCLUDE\]\s+(\d+)/){$i=$1;}
293 | if($i){
294 | if($c<=$i){print$l;$c++;}else{$c=0;$i=0;}
295 | }}
296 | close($f);
297 | }}' -- "${1}" "${2}"
298 | }
299 |
300 | #-- TODO: Package external files for inclusion.
301 | _sshi_package_include_files () {
302 | for I in "${SSHI_INC_FILES[@]}"; do
303 | [[ ${I} =~ ^([^:]+):([^:]+)$ ]] && {
304 | echo -ne "\"${BASH_REMATCH[1]}\" "
305 | echo -ne "\"${BASH_REMATCH[2]}\" "
306 | }
307 | echo "I: ${I}"
308 | done
309 | }
310 |
311 | #-- Retry execution of a task for a maximum number of tries, pausing
312 | # every 0.1[random] seconds.
313 | #
314 | # This is called using an eval. It outputs the results as R_O and R_T.
315 | _sshi_retry_task () {
316 | local OP=(${@})
317 | #- MR == Max. Retries before giving up.
318 | # Default is 2.
319 | local MR=2
320 | [[ "${OP[0]}" =~ ^[0-9\.]+$ ]] && {
321 | MR=${OP[0]}
322 | OP=("${OP[@]:1}")
323 | }
324 | #- TO == Wait this long for command to complete before failing the task.
325 | # Default is 0 (infinite).
326 | local TO=0
327 | [[ "${OP[0]}" =~ ^[0-9\.]+$ ]] && {
328 | TO=${OP[0]}
329 | OP=("${OP[@]:1}")
330 | }
331 | local OUT=
332 | local LP=1
333 | local CT=0
334 | while [ ${LP} -ge 1 ]; do
335 | CT=$((${CT}+1))
336 | [ ${TO} -eq 0 ] && {
337 | eval "OUT=\"$(${OP[@]}; LP=${?}; echo "\"; LP=${LP}")"
338 | } || {
339 | eval "OUT=\"$(START=${SECONDS};ERR=0;DONE=0;${OP[@]} 2>&1 || ERR=${?} & \
340 | CHILDPID=${!};echo -e "\";LP=\"${ERR}"; \
341 | while [ ${DONE} -lt 1 ]; do P=$(ps -ef|grep ${CHILDPID}|grep -v grep); \
342 | [ -z "${P}" ] && { DONE=1; } || { \
343 | [ $((${SECONDS} - ${START})) -ge ${TO} ] && { DONE=1; } || { \
344 | # echo "------------------------------------------" >> psout; \
345 | # echo "child pid: ${CHILDPID}" >> psout; \
346 | # echo "cmd: \"${OP[@]}\"" >> psout; \
347 | # ps -ef >> psout; \
348 | sleep 0.2;DONE=0; \
349 | };};done)\""
350 | # echo -e "OUT \"${OUT}\"" 1>&2
351 | }
352 |
353 | [ ${LP} -ge 1 ] && {
354 | [ ${CT} -ge ${MR} ] && break
355 | sleep "0.1${RANDOM}"
356 | }
357 | done
358 |
359 | echo -e "R_O=\"${OUT}\";R_T=${LP}"
360 | }
361 |
362 | #-- Use Perl for BASE64 encode/decode. This eliminates the need to
363 | # keep track of different encode/decode tools and their cmd line opts.
364 | local S_BE="perl -MMIME::Base64 -e '\$f=join(\"\",);print encode_base64(\$f,\"\");'"
365 | local S_BD="perl -MMIME::Base64 -e '\$f=join(\"\",);print decode_base64(\$f);'"
366 |
367 | #-- This will be populated with our "log command".
368 | local LC=
369 |
370 | #-- Get/set SSHI variable defaults.
371 | eval "$(_sshi_defaults)"
372 | eval "$(_sshi_scancnf ${SSHI_UC} ${SSHI_MC} ${@})"
373 |
374 | #-- Log file name format.
375 | local S_LFM="${SSH_HOST}-$(date +'%Y-%m-%d_%H-%M-%S').log"
376 |
377 | #-- Determine if we should log.
378 | [ -n "${SSHI_IS_SSH}" ] && [ -n "${SSHI_NO_LOG_REMOTE}" ] && {
379 | S_NL=1
380 | unset S_LF
381 |
382 | } || {
383 |
384 | #- Log by default. Turn off logging when requested.
385 | [ -n "${SSHI_LOG_BY_DEF}" ] && {
386 | [ -n "${S_NL}" ] && unset S_LG S_NL || S_LG=1
387 |
388 | } || {
389 |
390 | #- Do not log by default. Turn on logging when requested.
391 | [ -n "${S_LG}" ] && local S_LG=1
392 | }
393 |
394 | #- Make sure log location is writable.
395 | [ -n "${S_LG}" ] && {
396 | local S_LF="${SSHI_LOG_LOC}/${S_LFM}"
397 |
398 | #- Create SSH log directory if needed.
399 | [ -n "${SSHI_LOG_LOC}" ] && {
400 | [ -n ${SSHI_CREATE_LOG_LOC} ] && {
401 | [ ! -e ${SSHI_LOG_LOC} ] && {
402 | eval "$(_sshi_retry_task 1 1 mkdir -p ${SSHI_LOG_LOC})"
403 | }
404 | }
405 | }
406 |
407 | #- Make sure log directory is writeable. Try twice, after pausing for a bit.
408 | # The length is randomized to compensate for > 2 simultaneous SSH sessions
409 | # vying for the file.
410 | local WT=${SSHI_LOG_LOC}/.SSHI_WRITE_OK
411 | local S_E=0
412 | local OK=
413 |
414 | while [ -z "${OK}" ]; do
415 | eval "$(_sshi_retry_task 2 2 rm -f ${WT})"
416 | S_E=$((${S_E}+${R_T}))
417 | eval "$(_sshi_retry_task 2 2 touch ${WT})"
418 | S_E=$((${S_E}+${R_T}))
419 | [ ${S_E} = 0 ] && {
420 | OK=1
421 | } || {
422 | sleep "0.1${RANDOM}"
423 | }
424 | done
425 |
426 | [ ${S_E} -gt 0 ] && {
427 | _sshi_err "Unable to write to directory '${SSHI_LOG_LOC}'.\nSession will not be logged."
428 | unset S_LF
429 | } || {
430 | _sshi_clean_log_dir
431 | touch ${S_LF}
432 | }
433 | }
434 | }
435 |
436 | #- Had a problem with the embedded __sshi_l alias with older Perl versions.
437 | # Not going to figure it out for now.
438 | # We fall back to "tee -i", if the version is lower than 5.18.
439 | PC="perl -e 'use v5.18;' 2>/dev/null;[ \${?} -gt 0 ]&&{ echo;
440 | OPERL=1;echo '**** WARNING: Perl version is earlier than 5.18. ****';
441 | echo '**** Using tee -i for logging (NO OUTPUT FILTERING). ****';echo;}"
442 | eval "${PC}"
443 |
444 | #- A log file needs to be defined to log. Also, no logging when a remote
445 | # SSH command was entered via CLI.
446 | [ -n "${S_LF}" ] && [ -z "${SSHREMCMD}" ] && {
447 | [ -z "${OPERL}" ] && {
448 | LC="__sshi_l ${S_LF}"
449 | } || {
450 | LC="tee -i ${S_LF}"
451 | }
452 | }
453 |
454 | #- Skip prompt and rc file shipping if requested.
455 | [ -n "${NOPROMPT}" ] && unset S_F
456 |
457 | #- Parse things and connect if we have a matched entry in the SSH config.
458 | [ -n "${S_F}" ] && {
459 |
460 | #- PROMPTONLY set on a host .ssh/config. Set things accordingly.
461 | [ -n "${PROMPTONLY}" ] && {
462 | [ -n "${SSHI_RPS1}" ] && {
463 | echo "Connecting to ${S_F} with local prompt."
464 | [ -z "${SSHREMCMD}" ] &&
465 | SSHREMCMD="export PS1=\"${SSHI_RPS1}\";exec bash"
466 | }
467 | } || {
468 |
469 | #- The rcfile to use remotely. Regenerates every time you log in.
470 | # local .bashrc will be called at the end. Overrides can be defined on the remote.
471 | # This variable is exported for use on remote systems.
472 | [ -z "${RCPUSH}" ] && RCPUSH=".bashrc_pushed-${USER}"
473 |
474 | #- Add an alias to bash (use your customized bash env).
475 | local USH="alias bash='/bin/bash --rcfile ~/${RCPUSH}'"
476 |
477 | local RBASHRC_E=
478 | echo -e "Connecting to ${S_F} with local shell includes.\n"
479 |
480 | #- Gather aliases.
481 | local S_A=
482 | local OI=${IFS}
483 | IFS=$'\n'
484 | for A in $(alias); do
485 | #- Replace the __sshi_l alias, if an old Perl version was found locally.
486 | [[ "${A}" =~ ^alias\ __sshi_l ]] && {
487 | [ -n "${OPERL}" ] && {
488 | A="alias __sshi_l='tee -i'"
489 | }
490 | }
491 | S_A="${S_A}${A};"
492 | done
493 | IFS=${OI}
494 |
495 | #- Use RCPUSH file if in an SSH session. Allows you to reuse your shipped stuff when
496 | # using ssh on remote systems.
497 | # ** This only really matters when ssh is included in SSHI_ADD_SUBS.
498 | # Attempt to use pushed rc if SSH. Use local rc if non-SSH
499 | if [ -n "${SSHI_IS_SSH}" -a -e "~/${RCPUSH}" ]; then
500 | SSHI_BASH_RCFILES="~/${RCPUSH}"
501 | fi
502 |
503 | #- Retrieve SSHI_ADD_SUBS functions and [SSH_INCLUDE] lines.
504 | # Functions need to be decoded before 'source'ing them (for some reason).
505 | # Decoded output is piped to RCPUSH.funcs file, which is sourced from the
506 | # pushed rc file.
507 | local RFUNCS="export RCPUSH=${RCPUSH};$(_sshi_getrc "${SSHI_BASH_RCFILES}" "${SSHI_ADD_SUBS}")"
508 | local RFUNCS_E="sleep 0.2;echo \"$(echo "${RFUNCS}"|eval ${S_BE})\"|${S_BD}>~/${RCPUSH}.funcs;. ~/${RCPUSH}.funcs"
509 | RBASHRC_E="export SSHI_IS_SSH=1;${S_A}${RFUNCS_E}"
510 | [ -n "${SSHI_RPS1}" ] && RBASHRC_E+=";export PS1=\"${SSHI_RPS1}\""
511 | RBASHRC_E=${RBASHRC_E//\$/\\$}
512 | RBASHRC_E=${RBASHRC_E//\"/\\\"}
513 | [ -z "${SSHREMCMD}" ] &&
514 | SSHREMCMD="echo \"${RBASHRC_E}\">~/${RCPUSH};exec bash --rcfile ~/${RCPUSH}"
515 | }
516 | }
517 |
518 | #-- Compile the SSH command to run (including logging stuff) and run it.
519 | local SSHEXEC=("${SSHI_SSH_BIN}" ${SSH_OPTS})
520 | [ -n "${SSHREMCMD}" ] && SSHEXEC=(${SSHEXEC[@]} "-t" "${SSHREMCMD}")
521 |
522 | [ -n "${LC}" ] && {
523 | ${SSHEXEC[*]} | eval ${LC}
524 | } || {
525 | ${SSHEXEC[*]}
526 | }
527 |
528 | #-- Logging report.
529 | [ -n "${LC}" ] && echo "------------------------------" 1>&2
530 | [ -n "${S_LG}" ] && {
531 | [ -n "${S_LF}" ] && {
532 |
533 | #- Report the log file name, if it is not zero-length. Otherwise remove the file.
534 | [ -s "${S_LF}" ] && {
535 | echo "Session logged to ${S_LF}" 1>&2
536 | } || {
537 |
538 | #- Warn the user of zero-length log, and clear the file.
539 | [ -n "${LC}" ] && echo "No output logged from session. Removing ${S_LF}" 1>&2
540 | rm "${S_LF}"
541 | }
542 |
543 | #- Warn the user that we were unable to write the session log.
544 | } || {
545 | echo -ne "WARNING: Logging is enabled, but unable to write to log." 1>&2
546 | echo -e " Please verify that SSHI_LOG_LOC is correct." 1>&2
547 | }
548 | }
549 |
550 | }
551 |
552 | # vim: filetype=sh tabstop=1 expandtab
553 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published
637 | by the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------