- #!/bin/bash
- #==============================================================================
- # Copyright and license info is available in the LICENSE file included with
- # the Server Deployment Package (SDP), and also available online:
- # https://swarm.workshop.perforce.com/projects/perforce-software-sdp/view/main/LICENSE
- #------------------------------------------------------------------------------
- #==============================================================================
- # Declarations and Environment
- declare Version=4.4.5
- export P4CBIN=${P4CBIN:-/p4/common/bin}
- export SDP_ENV=${SDP_ENV:-$P4CBIN/p4_vars}
- export SDP_INSTANCE=${SDP_INSTANCE:-Unset}
- declare -i DEBUG=0
- declare -i SDP_ALWAYS_LOGIN=${SDP_ALWAYS_LOGIN:-0}
- declare -i LoginSuperUser=1
- declare -i LoginServiceUser=0
- declare -i LoginAutomationUsers=0
- declare AutomationUsers=${SDP_AUTOMATION_USERS:-""}
- declare AuthID=
- declare AuthServerPort=
- declare Cmd=
- declare ServiceUser=
- declare TargetServerPort=
- declare TicketExpiration=
- declare Port=Unset
- declare Log=Unset
- declare CmdLine="$0 $*"
- declare -i ShowLog=${SDP_SHOW_LOG:-0}
- declare -i OverallExitCode=0
- declare -i LoginCount=0
- declare TmpFile=
- declare P4DInitScript=
- declare GrepCmd=
- #==============================================================================
- # Local Functions
- # Micro-functions, one-liners used to avoid external dependencies.
- function msg () { if [[ "$Log" != Unset ]]; then echo -e "$*" >> "$Log"; else echo -e "$*"; fi; }
- function dbg () { [[ "$DEBUG" -eq 1 ]] || return; if [[ "$Log" != Unset ]]; then echo -e "DBG: $*" >> "$Log"; else echo -e "DBG: $*" >&2; fi; }
- function cmd () { msg "Executing: $*" >> "$Log"; "$@" >> "$Log" 2>&1; return $?; }
- function bail () { msg "\\nError: ${1:-Unknown Error}"; exit "${2:-1}"; }
- #------------------------------------------------------------------------------
- # Function: usage (required function)
- #
- # Input:
- # $1 - style, either -h (for short form) or -man (for man-page like format).
- # The default is -h.
- #
- # $2 - error message (optional). Specify this if usage() is called due to
- # user error, in which case the given message displayed first, followed by the
- # standard usage message (short or long depending on $1). If displaying an
- # error, usually $1 should be -h so that the longer usage message doesn't
- # obscure the error message.
- #
- # Sample Usage:
- # usage
- # usage -man
- # usage -h "Incorrect command line usage."
- #
- # This last example generates a usage error message followed by the short
- # '-h' usage summary.
- #------------------------------------------------------------------------------
- function usage
- {
- declare style=${1:--h}
- declare errorMessage=${2:-Unset}
- if [[ "$errorMessage" != Unset ]]; then
- echo -e "\\n\\nUsage Error:\\n\\n$errorMessage\\n\\n" >&2
- fi
- # tag::includeManual[]
- echo "USAGE for p4login v$Version:
- p4login [<instance>] [-p <port> | -service] [-automation] [-all]
- or
- p4login -h|-man
- "
- if [[ "$style" == -man ]]; then
- echo -e "DESCRIPTION:
- In its simplest form, this script simply logs in P4USER to P4PORT
- using the defined password access mechanism.
- It generates a login ticket for the SDP super user, defined by
- P4USER when sourcing the SDP standard shell environment. It is
- called from cron scripts, and so does not normally generate any
- output.
- If run on a replica with the -service option, the serviceUser defined
- for the given replica is logged in.
- The \$SDP_AUTOMATION_USERS variable can be defined in
- $P4CCFG/p4_N.vars. If defined, this should contain a
- comma-delimited list of automation users to be logged in when the
- -automation option is used. A definition might look like:
- export SDP_AUTOMATION_USERS=builder,trigger-admin,p4review
- Login behavior is affected by external factors:
- 1. P4AUTH, if defined, affects login behavior on replicas.
- 2. The auth.id setting, if defined, affects login behaviors (and
- generally simplifies them).
- 3. The \$SDP_ALWAYS_LOGIN variable. If set to 1, this causes p4login
- to always execute a 'p4 login' command to generate a login ticket,
- even if a 'p4 login -s' test indicates none is needed. By default,
- the login is skipped if a 'p4 login -s' test indicates a long-term
- ticket is available that expires 31+days in the future.
- Add \"export SDP_ALWYAYS_LOGIN=1\" to $P4CCFG/p4_N.vars to
- change the default for an instance, or to $P4CBIN/p4_vars to
- change it globally. If unset, the default is 0.
- 4. If the P4PORT contains an ssl: prefix, the P4TRUST relationship
- is checked, and if necessary, a p4 trust -f -y is done to establish
- trust.
- OPTIONS:
- <instance>
- Specify the SDP instances. If not specified, the SDP_INSTANCE
- environment variable is used instead. If the instance is not
- defined by a parameter and SDP_INSTANCE is not defined, p4login
- exists immediately with an error message.
- -service
- Specify -service when run on a replica or edge server to login
- the super user and the replication service user.
- This option is not compatible with '-p <port>'.
- -p <port>
- Specify a P4PORT value to login to, overriding the default
- defined by P4PORT setting in the environment. If operating
- on a host other than the master, and auth.id is set, this
- flag is ignored; the P4TARGET for the replica is used
- instead.
- This option is not compatible with '-service'.
- -automation
- Specify -automation to login external automation users defined
- by the \$SDP_AUTOMATION_USERS variable.
- -v Show output of login attempts, which is suppressed by default.
- Setting SDP_SHOW_LOG=1 in the shell environment has the same
- effect as -v.
- -L <log>
- Specify the log file to use. The default is /p4/N/logs/p4login.log
- -d Set debugging verbosity.
- -D Set extreme debugging verbosity.
- HELP OPTIONS:
- -h Display short help message
- -man Display man-style help message
- EXAMPLES:
- 1. Typical usage for automation, with instance SDP_INSTANCE defined
- in the environment by sourcing p4_vars, and logging in only the super
- user P4USER to P4PORT:
- source $P4CBIN/p4_vars abc
- p4login
- Login in only P4USER to the specified port, P4MASTERPORT in this example:
- p4login -p \$P4MASTERPORT
- Login the super user P4USER, and then login the replication serviceUser
- for the current ServerID:
- p4login -service
- Login external automation users (see SDP_AUTOMATION_USERS above):
- p4login -automation
- Login all users:
- p4login -all
- Or: p4login -service -automation
- LOGGING:
- This script generates no output by default. All (stdout and stderr) is
- logged to /p4/N/logs/p4login.log.
- The exception is usage errors, which result an error being sent to
- stderr followed usage info on stdout, followed by an immediate exit.
- If the '-v' flag is used, the contents of the log are displayed to
- stdout at the end of processing.
- EXIT CODES:
- An exit code of 0 indicates a valid login ticket exists, while a
- non-zero exit code indicates a failure to login.
- "
- # end::includeManual[]
- fi
- exit 1
- }
- #------------------------------------------------------------------------------
- # Function: trust_port ($port)
- #------------------------------------------------------------------------------
- function trust_port () {
- declare port=${1:-Unset}
- if [[ "$port" == "ssl:"* ]]; then
- dbg "Trust check."
- # Do a 'p4 trust' if needed.
- # shellcheck disable=SC2153
- "$P4BIN" -p "$port" -s info -s 2>/dev/null > "$TmpFile"
- if grep -q ' authenticity ' "$TmpFile"; then
- cmd "$P4BIN" -p "$port" trust -f -y
- rm -f "$TmpFile"
- return $?
- fi
- rm -f "$TmpFile"
- else
- return 0
- fi
- }
- #------------------------------------------------------------------------------
- # Function: login_user ($user, $port)
- # Login specified user into specified port.
- # Return 0 if successful, 1 if not.
- #------------------------------------------------------------------------------
- function login_user () {
- declare user=${1:-Unset}
- declare port=${2:-Unset}
- declare userType=
- dbg "CALL: login_user(user=$user, port=$port)"
- userType=$("$P4BIN" -ztag -F %Type% user -o "$user")
- # shellcheck disable=SC2153
- userType=$("$P4BIN" -ztag -F %Type% user -o "$user")
- userType=${userType:-Unknown}
- if [[ "$userType" != Unknown ]]; then
- msg "Logging user $user (type=$userType) into port: $port."
- else
- msg "Logging user $user into port: $port."
- fi
- TicketExpiration=$("$P4BIN" -ztag -F %TicketExpiration% -p "$port" -u "$user" login -s 2>/dev/null)
- if [[ "$TicketExpiration" =~ [0-9]+ ]]; then
- # A 'long-term' ticket is one that expires more than a month (31 days + 1 second) from now.
- if [[ "$TicketExpiration" -ge 2678401 ]]; then
- msg "User $user already logged into $P4PORT with a long-term ticket. Login not required."
- if [[ "$SDP_ALWAYS_LOGIN" -eq 1 ]]; then
- msg "Doing login anyway as SDP_ALWAYS_LOGIN is enabled."
- LoginCount=$((LoginCount+1))
- if [[ "$user" == "$P4USER" ]]; then
- Cmd="$P4BIN -p $port -u $user -s login -a"
- msg "Running: $Cmd"
- $Cmd < "$SDP_ADMIN_PASSWORD_FILE" >> "$Log" 2>&1 || return 1
- else
- if [[ "$userType" == service ]]; then
- Cmd="$P4BIN -p $port -u $P4USER -s login $user"
- else
- Cmd="$P4BIN -p $port -u $P4USER -s login -a $user"
- fi
- msg "Running: $Cmd"
- $Cmd >> "$Log" 2>&1 || return 1
- fi
- fi
- return 0
- else
- msg "Warning: User $user logged into $P4PORT with a short-term ticket. Attempting to extend."
- LoginCount=$((LoginCount+1))
- if [[ "$user" == "$P4USER" ]]; then
- Cmd="$P4BIN -p $port -u $P4USER -s login -a"
- msg "Running: $Cmd"
- $Cmd < "$SDP_ADMIN_PASSWORD_FILE" >> "$Log" 2>&1 || return 1
- else
- if [[ "$userType" == service ]]; then
- Cmd="$P4BIN -p $port -u $P4USER -s login $user"
- else
- Cmd="$P4BIN -p $port -u $P4USER -s login -a $user"
- fi
- msg "Running: $Cmd"
- $Cmd >> "$Log" 2>&1 || return 1
- fi
- fi
- else
- msg "User $user is not logged into $P4PORT. Attempting to login."
- LoginCount=$((LoginCount+1))
- if [[ "$user" == "$P4USER" ]]; then
- Cmd="$P4BIN -p $port -u $P4USER -s login -a"
- msg "Running: $Cmd"
- $Cmd < "$SDP_ADMIN_PASSWORD_FILE" >> "$Log" 2>&1 || return 1
- else
- # We cannot use the '-a' flag to 'p4 login' for service accounts, so
- # drop it for service accounts. Otherwise, '-a' is preferred for
- # robustness, since certain network interface card (NIC)
- # configurations with multiple IPs need tickets not bound to one of
- # multiple possible IPs. See 'p4 help login' for more.
- if [[ "$userType" == service ]]; then
- Cmd="$P4BIN -p $port -u $P4USER -s login $user"
- else
- Cmd="$P4BIN -p $port -u $P4USER -s login -a $user"
- fi
- msg "Running: $Cmd"
- $Cmd >> "$Log" 2>&1 || return 1
- fi
- fi
- }
- #==============================================================================
- # Command Line Processing
- declare -i shiftArgs=0
- set +u
- while [[ $# -gt 0 ]]; do
- case $1 in
- # Note: When If $LoginServiceUser is set to 1, the super user is
- # still logged in, but in a different block of code than the one
- # dedicated to logging, in only the super user, which applies
- # if LoginSuperUser=1.
- (-service) LoginSuperUser=0; LoginServiceUser=1;;
- (-automation) LoginSuperUser=0; LoginAutomationUsers=1;;
- (-all) LoginSuperUser=1; LoginServiceUser=1; LoginAutomationUsers=1;;
- (-h) usage -h;;
- (-man) usage -man;;
- (-p) Port=$2; shiftArgs=1;;
- (-v) ShowLog=1;;
- (-L) Log=$2; shiftArgs=1;;
- (-d) DEBUG=1;; # Debug; enable dbg() function calls.
- (-D) set -x;; # Debug; use 'set -x' mode.
- (-*) usage -h "Unknown command line option ($1).";;
- (*) export SDP_INSTANCE=$1;;
- esac
- # Shift (modify $#) the appropriate number of times.
- shift; while [[ "$shiftArgs" -gt 0 ]]; do
- [[ $# -eq 0 ]] && usage -h "Incorrect number of arguments."
- shiftArgs=$shiftArgs-1
- shift
- done
- done
- set -u
- #==============================================================================
- # Command Line Verification
- [[ "$SDP_INSTANCE" == Unset ]] && \
- bail "The \$SDP_INSTANCE setting is not defined. It must be defined by doing:\\n\\n\\tsource $P4CBIN/p4_vars <instance>\\n\\nor by passing in the instance name as a parameter to this script.\\n"
- #==============================================================================
- # Main Program
- # shellcheck disable=SC1090
- source "$SDP_ENV" "$SDP_INSTANCE" ||\
- bail "Failed to load SDP environment for instance $SDP_INSTANCE."
- # shellcheck disable=SC1090 disable=SC1091
- source "/p4/common/bin/backup_functions.sh" ||\
- bail "Failed to load backup_functions.sh."
- P4DInitScript="$P4HOME/bin/p4d_${SDP_INSTANCE}_init"
- # If /p4/N/bin/p4d_N is a symlink, the current instance is configured to be
- # case-sensitive, otherwise it is case-insensitive. (On a non-p4d server
- # machine, this value may be wrong, but this is of no consequence, as it is
- # only used on p4d server machines). When doing a 'grep' for $SERVERID,
- # use grep insensitive check if p4d is case-insensitive.
- if [[ -L "${P4DInitScript%_init}" ]]; then
- GrepCmd="grep"
- else
- GrepCmd="grep -i"
- fi
- TmpFile="${P4TMP:-/tmp}/.p4login.$$.$RANDOM"
- [[ "$Log" == Unset ]] && Log="$LOGS/p4login.$(date +'%Y%m%d-%H%M%S').log"
- rm -f "$Log"
- msg "${0##*/} v$Version Checking login status at $(date +'%a %Y-%m-%d %H:%M:%S %Z').\\nInitial command line:\\n$CmdLine"
- [[ "$Port" == Unset ]] && Port="$P4PORT"
- cmd "$P4BIN" set P4TICKETS
- if [[ -r "$P4ROOT/db.config" ]]; then
- copy_jd_table "db.config" "$P4ROOT"
- # shellcheck disable=SC2153,SC2154
- AuthID=$("$P4DBIN" -r "$JDTmpDir" -cshow | $GrepCmd -E "^(any|$SERVERID): auth.id" | head -1 | cut -d ' ' -f 4)
- else
- AuthID=UnknownAssumeEnabled
- fi
- if [[ "$LoginSuperUser" -eq 1 ]]; then
- if [[ -n "$SERVERID" && "$SERVERID" == "$P4MASTER_ID" ]]; then
- msg "Logging user $P4USER to port $Port."
- trust_port "$Port"
- dbg "C1 login_user ($P4USER, $Port)"
- login_user "$P4USER" "$Port" || OverallExitCode=1
- else
- # If not on the master, login to the P4TARGET if auth.id is set, else
- # just login as indicated. This implies that '-p <port>' is ignored
- # if auth.id is set.
- if [[ -n "$AuthID" ]]; then
- if [[ -r "$P4ROOT/db.config" ]]; then
- # shellcheck disable=SC2153
- TargetServerPort=$("$P4DBIN" -r "$JDTmpDir" -cshow | $GrepCmd "^${SERVERID}: P4TARGET" | cut -d ' ' -f 4)
- fi
- if [[ -n "$TargetServerPort" ]]; then
- trust_port "$TargetServerPort"
- dbg "C2.1 login_user ($P4USER, $TargetServerPort)"
- login_user "$P4USER" "$TargetServerPort" || OverallExitCode=1
- else
- trust_port "$Port"
- dbg "C2.2 login_user ($P4USER, $Port)"
- login_user "$P4USER" "$Port" || OverallExitCode=1
- fi
- else
- trust_port "$Port"
- dbg "C3 login_user ($P4USER, $Port)"
- login_user "$P4USER" "$Port" || OverallExitCode=1
- fi
- fi
- fi
- if [[ "$LoginServiceUser" -eq 1 ]]; then
- # If we are on a replica/edge, login the service user and super
- # user to the master server first, then to the local replica.
- if [[ -n "$SERVERID" && "$SERVERID" != "$P4MASTER_ID" ]]; then
- msg "\\nDoing replica/edge logins."
- if [[ -r "$P4ROOT/db.config" ]]; then
- TargetServerPort=$("$P4DBIN" -r "$JDTmpDir" -cshow | $GrepCmd "^${SERVERID}: P4TARGET" | cut -d ' ' -f 4)
- ServiceUser=$("$P4DBIN" -r "$JDTmpDir" -cshow | $GrepCmd "^${SERVERID}: serviceUser" | cut -d ' ' -f 4)
- fi
- if [[ -n "$AuthID" ]]; then
- msg "The auth.id configurable is set ($AuthID). Logging in to master P4PORT only."
- # Login the $P4USER super user first, whose password must match that
- # in the SDP admin password file ($SDP_ADMIN_PASSWORD_FILE).
- if [[ -n "$TargetServerPort" && -n "$ServiceUser" ]]; then
- trust_port "$TargetServerPort"
- dbg "C4.1 login_user ($P4USER, $TargetServerPort)"
- login_user "$P4USER" "$TargetServerPort" || OverallExitCode=1
- dbg "C4.2 login_user ($ServiceUser, $TargetServerPort)"
- login_user "$ServiceUser" "$TargetServerPort" || OverallExitCode=1
- else
- msg "\\nError: This is not the master (ServerID=$SERVERID), but could not determine P4TARGET and/or serviceUser for server $SERVERID."
- OverallExitCode=1
- trust_port "$TargetServerPort"
- dbg "C5.1 login_user ($P4USER, $TargetServerPort)"
- login_user "$P4USER" "$TargetServerPort"
- dbg "C5.2 login_user ($ServiceUser, $TargetServerPort)"
- login_user "$ServiceUser" "$TargetServerPort"
- fi
- else
- msg "The auth.id configurable is not set. Logging in to both local and P4TARGET ports."
- if [[ -n "$TargetServerPort" && -n "$ServiceUser" ]]; then
- trust_port "$TargetServerPort"
- dbg "C6.1 login_user ($P4USER, $TargetServerPort)"
- login_user "$P4USER" "$TargetServerPort" || OverallExitCode=1
- trust_port "$P4PORT"
- dbg "C6.2 login_user ($P4USER, $P4PORT)"
- login_user "$P4USER" "$P4PORT" || OverallExitCode=1
- dbg "C6.3 login_user ($ServiceUser, $TargetServerPort)"
- login_user "$ServiceUser" "$TargetServerPort" || OverallExitCode=1
- else
- msg "\\nError: This is not the master (ServerID=$SERVERID), but could not determine P4TARGET and/or serviceUser for server $SERVERID."
- OverallExitCode=1
- trust_port "$P4PORT"
- dbg "C7 login_user ($P4USER, $P4PORT)"
- login_user "$P4USER" "$P4PORT"
- fi
- # AuthServerPort is the P4AUTH server; it is not related to the
- # auth.id configurable. If a P4AUTH server is defined, we need to
- # login there, too.
- AuthServerPort=$("$P4BIN" -p "$P4PORT" configure show P4AUTH 2>/dev/null)
- if [[ -n "$AuthServerPort" ]]; then
- AuthServerPort=${AuthServerPort##*=}
- AuthServerPort=${AuthServerPort%% *}
- msg "Logging into P4AUTH server."
- trust_port "$AuthServerPort"
- dbg "C8 login_user ($ServiceUser, $AuthServerPort)"
- login_user "$ServiceUser" "$AuthServerPort" || OverallExitCode=1
- fi
- fi
- else
- msg "\\nOperating on master/commit server, skipping replica/edge logins."
- fi
- # Login to P4BROKERPORT unless auth.id is set, in which case it's not
- # necessary.
- if [[ -n "$P4BROKERPORT" && "$P4BROKERPORT" != Unset && -z "$AuthID" ]]; then
- msg "Logging $P4USER into broker."
- trust_port "$P4BROKERPORT"
- dbg "C9 login_user ($P4USER, $P4BROKERPORT)"
- login_user "$P4USER" "$P4BROKERPORT" || OverallExitCode=1
- fi
- fi
- if [[ "$LoginAutomationUsers" -eq 1 ]]; then
- # Login other automation users (which may or may not be super users)
- # using $P4USER's super powers to log them in without a password.
- if [[ -n "$AutomationUsers" ]]; then
- msg "\\nLogging in special automation users defined by \$SDP_AUTOMATION_USERS in $P4CCFG/${P4SERVER}.vars."
- for user in ${AutomationUsers//,/ }; do
- msg "Logging in user $user."
- dbg "C10 login_user ($user, $P4PORT)"
- trust_port "$P4PORT"
- login_user "$user" "$P4PORT" || OverallExitCode=1
- if [[ -z "$AuthID" ]]; then
- if [[ -n "$P4BROKERPORT" && "$P4BROKERPORT" != Unset ]]; then
- trust_port "$P4BROKERPORT"
- dbg "C11 login_user ($user, $P4BROKERPORT)"
- login_user "$user" "$P4BROKERPORT" || OverallExitCode=1
- fi
- fi
- done
- else
- msg "\\nError: The -automation flag was specified, but \$SDP_AUTOMATION_USERS is not defined in the environment. Check $P4CCFG/${P4SERVER}.vars."
- OverallExitCode=1
- fi
- fi
- if [[ "$OverallExitCode" -eq 0 ]]; then
- if [[ "$LoginCount" -gt 0 ]]; then
- msg "\\nSuccess: All logins were successful, $LoginCount login(s) were needed."
- else
- msg "\\nSuccess: No logins were needed."
- fi
- else
- msg "\\nError: Some logins were not successful; $LoginCount were attempted. Review the output above."
- fi
- [[ "$ShowLog" -eq 1 && -s "$Log" ]] && cat "$Log"
- # Overwrite p4login.log so it always has the contents of the last call
- # to p4login.
- if [[ "$Log" != "$LOGS/p4login.log" ]]; then
- cp -f "$Log" "$LOGS/p4login.log"
- fi
- remove_jd_tables
- exit "$OverallExitCode"
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#22 | 31204 | Will Kreitzmann | Released SDP 2024.2.31193 (2025/01/17). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
2 months ago | |
#21 | 31077 | C. Thomas Tyler | Released SDP 2024.2.31075 (2024/12/20). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
3 months ago | |
#20 | 30297 | C. Thomas Tyler | Released SDP 2023.2.30295 (2024/05/08). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
11 months ago | |
#19 | 29443 | C. Thomas Tyler | Released SDP 2022.2.29441 (2023/02/27). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
2 years ago | |
#18 | 27761 | C. Thomas Tyler | Released SDP 2020.1.27759 (2021/05/07). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
4 years ago | |
#17 | 27331 | C. Thomas Tyler | Released SDP 2020.1.27325 (2021/01/29). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
4 years ago | |
#16 | 25933 | C. Thomas Tyler | Released SDP 2019.2.25923 (2019/08/05). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
6 years ago | |
#15 | 25245 | C. Thomas Tyler | Released SDP 2019.1.25238 (2019/03/02). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
6 years ago | |
#14 | 23331 | C. Thomas Tyler | Released SDP 2017.4.23329 (2017/12/05). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
7 years ago | |
#13 | 23044 | C. Thomas Tyler | Released SDP 2017.3.23041 (2017/10/24). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
7 years ago | |
#12 | 20839 | C. Thomas Tyler | Fixed quoting bug in p4login. | 8 years ago | |
#11 | 20792 | C. Thomas Tyler | Released SDP 2016.2.20790 (2016/09/30). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
8 years ago | |
#10 | 20767 | C. Thomas Tyler | Released SDP 2016.2.20755 (2016/09/29). Copy Up using 'p4 copy -r -b perforce_software-sd...p-dev'. « |
8 years ago | |
#9 | 20353 | C. Thomas Tyler | Released SDP 2016.1.20348. Copy Up using 'p4 copy -r -b perforce_software-sdp-dev', with... selective removal of changes related to work-in-progress changes. « |
9 years ago | |
#8 | 20050 | C. Thomas Tyler | Released: 2016.1.20028 (2016/08/03). Copy Up using 'p4 copy -r -b perforce_software-sdp-d...ev'. « |
9 years ago | |
#7 | 18530 | Russell C. Jackson (Rusty) | Update main from dev. | 9 years ago | |
#6 | 15865 | Russell C. Jackson (Rusty) | Removed space between $ and Log | 10 years ago | |
#5 | 15856 | C. Thomas Tyler | Replaced the big license comment block with a shortened form referencing the LICENSE file... included with the SDP package, and also by the URL for the license file in The Workshop. « |
10 years ago | |
#4 | 15609 | C. Thomas Tyler | Pushing SDP 2015.1.15607 (2015/09/02). | 10 years ago | |
#3 | 13908 | C. Thomas Tyler | Pushing SDP 2015.1.13906. | 10 years ago | |
#2 | 12171 | Russell C. Jackson (Rusty) | Merge in changes to remove the need for p4master_run. | 10 years ago | |
#1 | 10148 | C. Thomas Tyler | Promoted the Perforce Server Deployment Package to The Workshop. | 11 years ago |