{"id":226,"date":"2021-07-23T12:25:54","date_gmt":"2021-07-23T12:25:54","guid":{"rendered":"https:\/\/ssdsunucum.com\/blog\/how-to-create-a-custom-transport-script-for-backups\/"},"modified":"2021-07-23T12:25:54","modified_gmt":"2021-07-23T12:25:54","slug":"how-to-create-a-custom-transport-script-for-backups","status":"publish","type":"post","link":"https:\/\/ssdsunucum.com\/blog\/how-to-create-a-custom-transport-script-for-backups\/","title":{"rendered":"How to Create a Custom Transport Script for Backups"},"content":{"rendered":"<\/p>\n<div class=\"col-md-9\">\n<div class=\"flex-column flex-md-row article-header\">\n<div id=\"versioned-article-header\">\n<p class=\"valid-version-info\"><em>Valid for versions 82 through the latest version<\/em><\/p>\n<\/div>\n<div id=\"version-select-group\" aria-label=\"select versions\">\n<h4>Version:<\/h4>\n<h4>82<\/h4>\n<\/div><\/div>\n<hr>\n<h2 id=\"overview\">Overview<\/h2>\n<div class=\"callout callout-danger\">\n<div class=\"callout-heading\">Warning:<\/div>\n<div class=\"callout-content\">\n<p><strong>Only<\/strong> advanced users should create custom transport scripts. Other users can try one of WHM\u2019s other options:<\/p>\n<ul>\n<li>A local directory<\/li>\n<li>Amazon S3\u2122<\/li>\n<li>Backblaze B2<\/li>\n<li>FTP<\/li>\n<li>Google Drive\u2122<\/li>\n<li>Rsync<\/li>\n<li>S3 Compatible<\/li>\n<li>SFTP<\/li>\n<li>WebDAV<\/li>\n<\/ul><\/div>\n<\/div>\n<p>The <em>Backup Configuration<\/em> feature allows users to create a custom destination for their backups.<\/p>\n<h2 id=\"create-a-custom-transport-script\">Create a custom transport script<\/h2>\n<p>The custom transport script is a script that you must provide for each custom backup destination that you set up in WHM\u2019s <em>Backup Configuration<\/em> interface (<em>WHM &gt;&gt; Home &gt;&gt; Backups &gt;&gt; Backup Configuration<\/em>). You can enter the transport script\u2019s absolute path via the <em>Script<\/em> setting for the <em>Custom<\/em> destination type in the <em>Additional Destinations<\/em> section.<\/p>\n<h3 id=\"script-operation\">Script operation<\/h3>\n<p>The following rules affect how the script interacts with the system:<\/p>\n<ul>\n<li>The script runs once per command.<\/li>\n<li>The script <strong>cannot<\/strong> save state information between commands.<\/li>\n<li>The system does <em>not<\/em> reuse the connection between commands. Instead, each time that the script runs, the system creates the connection to the remote custom destination, and then drops it after the script runs.<\/li>\n<\/ul>\n<p>The system passes information to the script, through the command line, in the following order:<\/p>\n<ol>\n<li>Command name.<\/li>\n<li>Current directory.<\/li>\n<li>Command specific parameters.<\/li>\n<li>Host.<\/li>\n<li>Username.<\/li>\n<\/ol>\n<p>The system passes the password information to the script through the environment.<\/p>\n<h3 id=\"script-commands\">Script commands<\/h3>\n<p>The script must implement the following commands:<\/p>\n<table>\n<thead>\n<tr>\n<th>Command<\/th>\n<th>Description<\/th>\n<th>Parameters<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>chdir<\/code><\/td>\n<td>This command changes directories on the remote destination. It is equivalent to the <code>cd<\/code> command on the command line.<\/td>\n<td><code>$path<\/code> \u2014 A file path.<\/td>\n<\/tr>\n<tr>\n<td><code>delete<\/code><\/td>\n<td>This command deletes an individual file on the remote destination.<\/td>\n<td><code>$path<\/code> \u2014 A file path.<\/td>\n<\/tr>\n<tr>\n<td><code>get<\/code><\/td>\n<td>This command copies a remote file to a local destination.<\/td>\n<td>\n<ul>\n<li><code>$dest_root_dir<\/code> \u2014 The remote directory.<\/li>\n<li><code>$dest_file<\/code> \u2014 The remote file name.<\/li>\n<li><code>$local_file<\/code> \u2014 The full path to the local file.<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td><code>ls<\/code><\/td>\n<td>This command prints identical output to the <code>ls -l<\/code> command.<\/td>\n<td><code>$path<\/code> \u2014 A file path.<\/td>\n<\/tr>\n<tr>\n<td><code>mkdir<\/code><\/td>\n<td>This command creates a directory on the remote destination.<\/td>\n<td><code>$path<\/code> \u2014 A file path.<\/td>\n<\/tr>\n<tr>\n<td><code>put<\/code><\/td>\n<td>This command copies a local file to a remote destination.<\/td>\n<td>\n<ul>\n<li><code>$dest_root_dir<\/code> \u2014 The remote directory.<\/li>\n<li><code>$dest_file<\/code> \u2014 The remote file name.<\/li>\n<li><code>$local_file<\/code> \u2014 The full path to the local file.<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td><code>rmdir<\/code><\/td>\n<td>This command deletes a directory on the remote destination. We <strong>strongly<\/strong> recommend that you verify the path that you plan to delete. If you pass the root directory (<code>\/<\/code>) as the path to delete, your system will experience <strong>serious<\/strong> problems.<\/td>\n<td><code>$path<\/code> \u2014 A file path.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Backups run each of these commands individually while the system transports the backup file and validates the destination.<\/p>\n<p>Your script should return any output to <code>STDOUT<\/code> to return data to the user.<\/p>\n<div class=\"callout callout-info\">\n<div class=\"callout-heading\">Note:<\/div>\n<div class=\"callout-content\">\n<p>If the script fails, it prints the output to <code>STDERR<\/code>. The system logs any data that the script returns to <code>STDERR<\/code> as part of the failure.<\/p>\n<\/p><\/div>\n<\/div>\n<h2 id=\"templates\">Templates<\/h2>\n<p>You can use the <code>\/usr\/local\/cpanel\/scripts\/custom_backup_destination.pl.skeleton<\/code> script in cPanel &#038; WHM as a template to create your own <code>custom_backup_destination.pl<\/code> script. For a sample backup transport script, see the <code>\/usr\/local\/cpanel\/scripts\/custom_backup_destination.pl.sample<\/code> script.<\/p>\n<div class=\"collapse-wrapper\">\n<p>        Click to view&#8230;<\/p>\n<div class=\"collapse\" id=\"click-to-view---1626990044908246549\">\n<div class=\"card card-body\">\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  7\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  8\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  9\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 10\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 11\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 12\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 13\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 14\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 15\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 16\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 17\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 18\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 19\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 20\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 21\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 22\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 23\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 24\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 25\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 26\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 27\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 28\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 29\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 30\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 31\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 32\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 33\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 34\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 35\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 36\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 37\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 38\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 39\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 40\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 41\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 42\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 43\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 44\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 45\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 46\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 47\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 48\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 49\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 50\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 51\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 52\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 53\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 54\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 55\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 56\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 57\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 58\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 59\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 60\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 61\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 62\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 63\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 64\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 65\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 66\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 67\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 68\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 69\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 70\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 71\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 72\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 73\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 74\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 75\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 76\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 77\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 78\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 79\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 80\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 81\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 82\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 83\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 84\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 85\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 86\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 87\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 88\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 89\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 90\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 91\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 92\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 93\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 94\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 95\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 96\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 97\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 98\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 99\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">100\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">101\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">102\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">103\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">104\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">105\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">106\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">107\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">108\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">109\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">110\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">111\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">112\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">113\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">114\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">115\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">116\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">117\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">118\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">119\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">120\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">121\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">122\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">123\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">124\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">125\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#75715e\">#!\/usr\/local\/cpanel\/3rdparty\/bin\/perl<\/span>\n\n<span style=\"color:#75715e\"># cpanel - scripts\/custom_backup_destination.pl.skeleton      Copyright 2021 cPanel, L.L.C<\/span>\n<span style=\"color:#75715e\">#                                                           All rights Reserved.<\/span>\n<span style=\"color:#75715e\"># copyright@cpanel.net                                         http:\/\/cpanel.net<\/span>\n<span style=\"color:#75715e\"># This code is subject to the cPanel license. Unauthorized copying is prohibited<\/span>\n\n<span style=\"color:#66d9ef\">use<\/span> strict;\n<span style=\"color:#66d9ef\">use<\/span> warnings;\n\n<span style=\"color:#75715e\"># These are the commands that a custom destination script must process<\/span>\n<span style=\"color:#66d9ef\">my<\/span> %commands <span style=\"color:#f92672\">=<\/span> (\n    put    <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_put,\n    get    <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_get,\n    ls     <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_ls,\n    mkdir  <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_mkdir,\n    chdir  <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_chdir,\n    rmdir  <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_rmdir,\n    delete <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_delete,\n);\n\n<span style=\"color:#75715e\"># There must be at least the command and the local directory<\/span>\nusage() <span style=\"color:#66d9ef\">if<\/span> ( @ARGV <span style=\"color:#f92672\">&lt;<\/span> <span style=\"color:#ae81ff\">2<\/span> );\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># The command line arguments passed to the script will be in the following order:<\/span>\n<span style=\"color:#75715e\"># command, local_directory, command arguments, and optionally, host, user password<\/span>\n<span style=\"color:#75715e\"># The local directory is passed in so we know from which directory to run the command<\/span>\n<span style=\"color:#75715e\"># We need to pass this in each time since we start the script fresh for each command<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">my<\/span> ( $cmd, $local_dir, @args ) <span style=\"color:#f92672\">=<\/span> @ARGV;\n\n<span style=\"color:#75715e\"># complain if the command does not exist<\/span>\nusage() <span style=\"color:#66d9ef\">unless<\/span> exists $commands{$cmd};\n\n<span style=\"color:#75715e\"># Run our command<\/span>\n$commands{$cmd}<span style=\"color:#f92672\">-&gt;<\/span>(@args);\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># This script should only really be executed by the custom backup destination type<\/span>\n<span style=\"color:#75715e\"># If someone executes it directly out of curiosity, give them usage info<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">usage<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> @cmds <span style=\"color:#f92672\">=<\/span> sort keys %commands;\n    <span style=\"color:#66d9ef\">print<\/span> STDERR <span style=\"color:#e6db74\">\"This script is for implementing a custom backup destinationn\"<\/span>;\n    <span style=\"color:#66d9ef\">print<\/span> STDERR <span style=\"color:#e6db74\">\"It requires the following arguments:  cmd, local_dir, cmd_argsn\"<\/span>;\n    <span style=\"color:#66d9ef\">print<\/span> STDERR <span style=\"color:#e6db74\">\"These are the valid commands:  @cmdsn\"<\/span>;\n    exit <span style=\"color:#ae81ff\">1<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># This portion contains the implementations for the various commands<\/span>\n<span style=\"color:#75715e\"># that the script needs to support in order to implement a custom destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Copy a local file to a remote destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_put<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $local, $remote, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Copy a remote file to a local destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_get<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $remote, $local, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Print out the results of doing an ls operation<\/span>\n<span style=\"color:#75715e\"># The calling program will expect the data to be<\/span>\n<span style=\"color:#75715e\"># in the format supplied by 'ls -l' and have it<\/span>\n<span style=\"color:#75715e\"># printed to STDOUT<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_ls<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Create a directory on the remote destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_mkdir<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $recurse, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Change into a directory on the remote destination<\/span>\n<span style=\"color:#75715e\"># This does not have the same meaning as it normally would since the script<\/span>\n<span style=\"color:#75715e\"># is run anew for each command call.<\/span>\n<span style=\"color:#75715e\"># This needs to do the operation to ensure it doesn't fail<\/span>\n<span style=\"color:#75715e\"># then print the new resulting directory that the calling program<\/span>\n<span style=\"color:#75715e\"># will pass in as the local directory for subsequent calls<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_chdir<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Recursively delete a directory on the remote destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_rmdir<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Delete an individual file on the remote destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_delete<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n    <span style=\"color:#66d9ef\">return<\/span>;\n}<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div><\/div>\n<\/p><\/div>\n<\/div>\n<div class=\"collapse-wrapper\">\n<p>        View the custom_backup_destination.pl.sample script&#8230;<\/p>\n<div class=\"collapse\" id=\"view-the-custom_backup_destination-pl-sample-script---1626990044929241566\">\n<div class=\"card card-body\">\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  7\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  8\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">  9\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 10\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 11\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 12\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 13\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 14\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 15\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 16\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 17\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 18\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 19\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 20\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 21\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 22\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 23\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 24\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 25\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 26\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 27\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 28\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 29\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 30\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 31\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 32\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 33\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 34\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 35\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 36\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 37\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 38\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 39\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 40\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 41\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 42\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 43\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 44\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 45\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 46\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 47\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 48\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 49\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 50\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 51\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 52\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 53\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 54\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 55\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 56\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 57\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 58\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 59\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 60\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 61\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 62\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 63\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 64\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 65\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 66\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 67\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 68\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 69\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 70\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 71\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 72\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 73\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 74\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 75\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 76\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 77\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 78\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 79\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 80\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 81\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 82\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 83\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 84\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 85\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 86\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 87\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 88\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 89\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 90\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 91\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 92\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 93\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 94\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 95\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 96\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 97\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 98\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 99\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">100\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">101\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">102\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">103\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">104\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">105\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">106\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">107\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">108\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">109\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">110\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">111\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">112\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">113\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">114\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">115\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">116\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">117\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">118\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">119\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">120\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">121\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">122\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">123\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">124\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">125\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">126\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">127\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">128\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">129\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">130\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">131\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">132\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">133\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">134\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">135\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">136\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">137\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">138\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">139\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">140\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">141\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">142\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">143\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">144\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">145\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">146\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">147\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">148\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">149\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">150\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">151\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">152\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">153\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">154\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">155\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">156\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">157\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">158\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">159\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">160\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">161\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">162\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">163\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">164\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">165\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">166\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">167\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">168\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">169\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">170\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">171\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">172\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">173\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">174\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">175\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">176\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">177\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">178\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">179\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">180\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">181\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">182\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">183\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">184\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">185\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">186\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">187\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">188\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">189\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">190\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">191\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">192\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">193\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">194\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">195\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">196\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">197\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">198\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">199\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">200\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">201\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">202\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">203\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">204\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">205\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">206\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">207\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">208\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">209\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">210\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">211\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">212\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">213\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">214\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">215\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#75715e\">#!\/usr\/local\/cpanel\/3rdparty\/bin\/perl<\/span>\n\n<span style=\"color:#75715e\"># cpanel - scripts\/custom_backup_destination.pl.sample      Copyright 2013 cPanel, L.L.C<\/span>\n<span style=\"color:#75715e\">#                                                           All rights Reserved.<\/span>\n<span style=\"color:#75715e\"># copyright@cpanel.net                                         http:\/\/cpanel.net<\/span>\n<span style=\"color:#75715e\"># This code is subject to the cPanel license. Unauthorized copying is prohibited<\/span>\n\n<span style=\"color:#66d9ef\">use<\/span> strict;\n<span style=\"color:#66d9ef\">use<\/span> warnings;\n<span style=\"color:#66d9ef\">use<\/span> Cwd <span style=\"color:#e6db74\">qw(getcwd abs_path)<\/span>;\n<span style=\"color:#66d9ef\">use<\/span> File::Spec;\n<span style=\"color:#66d9ef\">use<\/span> File::Copy;\n<span style=\"color:#66d9ef\">use<\/span> File::Path <span style=\"color:#e6db74\">qw(make_path remove_tree)<\/span>;\n<span style=\"color:#66d9ef\">use<\/span> autodie <span style=\"color:#e6db74\">qw(:all copy)<\/span>;\n\n<span style=\"color:#75715e\"># These are the commands that a custom destination script must process<\/span>\n<span style=\"color:#66d9ef\">my<\/span> %commands <span style=\"color:#f92672\">=<\/span> (\n    put    <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_put,\n    get    <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_get,\n    ls     <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_ls,\n    mkdir  <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_mkdir,\n    chdir  <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_chdir,\n    rmdir  <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_rmdir,\n    delete <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_delete,\n);\n\n<span style=\"color:#75715e\"># There must be at least the command and the local directory<\/span>\nusage() <span style=\"color:#66d9ef\">if<\/span> ( @ARGV <span style=\"color:#f92672\">&lt;<\/span> <span style=\"color:#ae81ff\">2<\/span> );\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># The command line arguments passed to the script will be in the following order:<\/span>\n<span style=\"color:#75715e\"># command, local_directory, command arguments, and optionally, host and user<\/span>\n<span style=\"color:#75715e\"># The local directory is passed in so we know from which directory to run the command<\/span>\n<span style=\"color:#75715e\"># we need to pass this in each time since we start the script fresh for each command<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">my<\/span> ( $cmd, $local_dir, @args ) <span style=\"color:#f92672\">=<\/span> @ARGV;\n\n<span style=\"color:#75715e\"># complain if the command does not exist<\/span>\nusage() <span style=\"color:#66d9ef\">unless<\/span> exists $commands{$cmd};\n\n<span style=\"color:#75715e\"># For this example transport, we are going to simply copy everything under this directory<\/span>\n<span style=\"color:#66d9ef\">my<\/span> $dest_root_dir <span style=\"color:#f92672\">=<\/span> <span style=\"color:#e6db74\">'\/custom_transport_demo'<\/span>;\nmkdir $dest_root_dir <span style=\"color:#66d9ef\">unless<\/span> <span style=\"color:#f92672\">-<\/span>d $dest_root_dir;\n\n<span style=\"color:#75715e\"># Step into the local directory<\/span>\n<span style=\"color:#75715e\"># This will be under the directory that we have as the file destination<\/span>\n$local_dir <span style=\"color:#f92672\">=<\/span> File::Spec<span style=\"color:#f92672\">-&gt;<\/span>catdir( $dest_root_dir, $local_dir );\nmake_path($local_dir) <span style=\"color:#66d9ef\">unless<\/span> <span style=\"color:#f92672\">-<\/span>d $local_dir;\nchdir $local_dir;\n\n<span style=\"color:#75715e\"># Run our command<\/span>\n$commands{$cmd}<span style=\"color:#f92672\">-&gt;<\/span>(@args);\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># This script should only really be executed by the custom backup destination type<\/span>\n<span style=\"color:#75715e\"># If someone executes it directly out of curiosity, give them usage info<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">usage<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> @cmds <span style=\"color:#f92672\">=<\/span> sort keys %commands;\n    <span style=\"color:#66d9ef\">print<\/span> STDERR <span style=\"color:#e6db74\">\"This script is for implementing a custom backup destinationn\"<\/span>;\n    <span style=\"color:#66d9ef\">print<\/span> STDERR <span style=\"color:#e6db74\">\"It requires the following arguments:  cmd, local_dir, cmd_argsn\"<\/span>;\n    <span style=\"color:#66d9ef\">print<\/span> STDERR <span style=\"color:#e6db74\">\"These are the valid commands:  @cmdsn\"<\/span>;\n    exit <span style=\"color:#ae81ff\">1<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Convert a path to be under our destination directory<\/span>\n<span style=\"color:#75715e\"># Absolute paths will be directly under it,<\/span>\n<span style=\"color:#75715e\"># relative paths will be relative to the local directory<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">convert_path<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ($path) <span style=\"color:#f92672\">=<\/span> @_;\n\n    <span style=\"color:#66d9ef\">if<\/span> ( $path <span style=\"color:#f92672\">=~<\/span> m<span style=\"color:#f92672\">|^\/|<\/span> ) {\n        $path <span style=\"color:#f92672\">=<\/span> File::Spec<span style=\"color:#f92672\">-&gt;<\/span>catdir( $dest_root_dir, $path );\n    }\n    <span style=\"color:#66d9ef\">else<\/span> {\n        $path <span style=\"color:#f92672\">=<\/span> File::Spec<span style=\"color:#f92672\">-&gt;<\/span>catdir( $local_dir, $path );\n    }\n\n    <span style=\"color:#66d9ef\">return<\/span> $path;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Convert a full path to the path under the the directory<\/span>\n<span style=\"color:#75715e\"># where we copy all the files<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">get_sub_directory<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ($path) <span style=\"color:#f92672\">=<\/span> @_;\n\n    <span style=\"color:#75715e\"># The first part will be the destination root directory,<\/span>\n    <span style=\"color:#75715e\"># Remove that part of the path and we will have the subdirectory<\/span>\n    $path <span style=\"color:#f92672\">=~<\/span> s<span style=\"color:#f92672\">|^<\/span>$dest_root_dir<span style=\"color:#f92672\">||<\/span>;\n\n    <span style=\"color:#66d9ef\">return<\/span> $path;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># This portion contains the implementations for the various commands<\/span>\n<span style=\"color:#75715e\"># that the script needs to support in order to implement a custom destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Copy a local file to a remote destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_put<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $local, $remote, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $remote <span style=\"color:#f92672\">=<\/span> convert_path($remote);\n\n    <span style=\"color:#75715e\"># Make sure the full destination directory exists<\/span>\n    <span style=\"color:#66d9ef\">my<\/span> ( undef, $dir, undef ) <span style=\"color:#f92672\">=<\/span> File::Spec<span style=\"color:#f92672\">-&gt;<\/span>splitpath($remote);\n    make_path($dir) <span style=\"color:#66d9ef\">unless<\/span> ( $dir <span style=\"color:#f92672\">and<\/span> <span style=\"color:#f92672\">-<\/span>d $dir );\n    copy( $local, $remote );\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Copy a remote file to a local destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_get<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $remote, $local, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $remote <span style=\"color:#f92672\">=<\/span> convert_path($remote);\n\n    copy( $remote, $local );\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Print out the results of doing an ls operation<\/span>\n<span style=\"color:#75715e\"># The calling program will expect the data to be<\/span>\n<span style=\"color:#75715e\"># in the format supplied by 'ls -l' and have it<\/span>\n<span style=\"color:#75715e\"># printed to STDOUT<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_ls<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $path <span style=\"color:#f92672\">=<\/span> convert_path($path);\n\n    <span style=\"color:#75715e\"># Cheesy, but this is a demo<\/span>\n    <span style=\"color:#66d9ef\">my<\/span> $ls <span style=\"color:#f92672\">=<\/span> <span style=\"color:#e6db74\">`ls -al $path`<\/span>;\n\n    <span style=\"color:#75715e\"># Remove the annoying 'total' line<\/span>\n    $ls <span style=\"color:#f92672\">=~<\/span> s<span style=\"color:#f92672\">|^<\/span>total[<span style=\"color:#f92672\">^<\/span>n]<span style=\"color:#f92672\">*<\/span>n<span style=\"color:#f92672\">||<\/span>;\n\n    <span style=\"color:#66d9ef\">print<\/span> $ls;\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Create a directory on the remote destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_mkdir<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $recurse, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $path <span style=\"color:#f92672\">=<\/span> convert_path($path);\n\n    make_path($path);\n\n    die <span style=\"color:#e6db74\">\"Failed to create $path\"<\/span> <span style=\"color:#66d9ef\">unless<\/span> <span style=\"color:#f92672\">-<\/span>d $path;\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Change into a directory on the remote destination<\/span>\n<span style=\"color:#75715e\"># This does not have the same meaning as it normally would since the script<\/span>\n<span style=\"color:#75715e\"># is run anew for each command call.<\/span>\n<span style=\"color:#75715e\"># This needs to do the operation to ensure it doesn't fail<\/span>\n<span style=\"color:#75715e\"># then print the new resulting directory that the calling program<\/span>\n<span style=\"color:#75715e\"># will pass in as the local directory for subsequent calls<\/span>\n<span style=\"color:#75715e\">#<\/span>\n\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_chdir<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $path <span style=\"color:#f92672\">=<\/span> convert_path($path);\n    chdir $path;\n\n    <span style=\"color:#66d9ef\">print<\/span> get_sub_directory( getcwd() ) <span style=\"color:#f92672\">.<\/span> <span style=\"color:#e6db74\">\"n\"<\/span>;\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Recursively delete a directory on the remote destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_rmdir<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $path <span style=\"color:#f92672\">=<\/span> convert_path($path);\n\n    remove_tree($path);\n\n    die <span style=\"color:#e6db74\">\"$path still exists\"<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#f92672\">-<\/span>d $path;\n    <span style=\"color:#66d9ef\">return<\/span>;\n}\n\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#75715e\"># Delete an individual file on the remote destination<\/span>\n<span style=\"color:#75715e\">#<\/span>\n<span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_delete<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $path <span style=\"color:#f92672\">=<\/span> convert_path($path);\n\n    unlink $path;\n    <span style=\"color:#66d9ef\">return<\/span>;\n}<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div><\/div>\n<\/p><\/div>\n<\/div>\n<p>The system passes most variables as arguments to the command line. If your script does <strong>not<\/strong> pass one of the hardcoded arguments to the core functions, the system will display all valid arguments in the global <code>%commands<\/code> hash.<\/p>\n<h2 id=\"code-examples\">Code examples<\/h2>\n<h4 id=\"use-statements\">Use statements<\/h4>\n<p>Begin the script with the standard <code>use<\/code> statements. Include any modules that you may need for your transport:<\/p>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">7\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">use<\/span> strict;\n<span style=\"color:#66d9ef\">use<\/span> warnings;\n<span style=\"color:#66d9ef\">use<\/span> Cwd <span style=\"color:#e6db74\">qw(getcwd abs_path)<\/span>;\n<span style=\"color:#66d9ef\">use<\/span> File::Spec;\n<span style=\"color:#66d9ef\">use<\/span> File::Copy;\n<span style=\"color:#66d9ef\">use<\/span> File::Path <span style=\"color:#e6db74\">qw(make_path remove_tree)<\/span>;\n<span style=\"color:#66d9ef\">use<\/span> autodie <span style=\"color:#e6db74\">qw(:all copy)<\/span>;<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<h4 id=\"the-commands-list\">The %commands list<\/h4>\n<div class=\"callout callout-info\">\n<div class=\"callout-heading\">Note:<\/div>\n<div class=\"callout-content\">\n<p>The script can only process the following commands.<\/p>\n<\/p><\/div>\n<\/div>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">7\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">8\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">9\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">my<\/span> %commands <span style=\"color:#f92672\">=<\/span> (\n    put    <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_put,\n    get    <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_get,\n    ls     <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_ls,\n    mkdir  <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_mkdir,\n    chdir  <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_chdir,\n    rmdir  <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_rmdir,\n    delete <span style=\"color:#f92672\">=&gt;<\/span> <span style=\"color:#f92672\">&<\/span>my_delete,\n);<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<h3 id=\"the-command-subroutines\">The %command subroutines<\/h3>\n<p>Every call to the script begins with a command and a local directory. You <strong>must<\/strong> pass the command line arguments in the following order:<\/p>\n<ul>\n<li><code>$cmd<\/code> \u2014 The command.<\/li>\n<li><code>$local_dir<\/code> \u2014 The local directory.<\/li>\n<li><code>@args<\/code> \u2014 The command\u2019s arguments.<\/li>\n<li><code>$host<\/code> \u2014 Optional. The remote destination\u2019s hostname or IP address.<\/li>\n<li><code>$user<\/code> \u2014 Optional. The remote destination\u2019s account username.<\/li>\n<li><code>$password<\/code> \u2014 Optional. The remote destination\u2019s password.<\/li>\n<\/ul>\n<p>Use the arguments that are specific to each of the commands and variables.<\/p>\n<div class=\"callout callout-info\">\n<div class=\"callout-heading\">Note:<\/div>\n<div class=\"callout-content\">\n<ul>\n<li>You should only include the optional <code>$host<\/code>, <code>$user<\/code>, and <code>$password<\/code> values if you configured them in the transport.<\/li>\n<li>If you include the <code>$password<\/code> value, you <strong>must<\/strong> use the <code>ENV<\/code> hash.<\/li>\n<li>You <strong>must<\/strong> include the <code>$local_dir<\/code> variable in every command subroutine that you create because the script calls each command individually.<\/li>\n<\/ul><\/div>\n<\/div>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">3\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">my<\/span> ( $cmd, $local_dir, @args, $host, $user ) <span style=\"color:#f92672\">=<\/span> @ARGV;\n<span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n usage() <span style=\"color:#66d9ef\">unless<\/span> exists $commands{$cmd};<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<h3 id=\"the-put-functions\">The put functions<\/h3>\n<p>The <code>put<\/code> function directs the script to upload or copy a local file to a remote destination. This function works similarly to the FTP <code>put<\/code> command.<\/p>\n<div class=\"callout callout-info\">\n<div class=\"callout-heading\">Note:<\/div>\n<div class=\"callout-content\">\n<p>For more robust transports, we <strong>strongly<\/strong> recommend that you perform several error checks for each step to ensure that the system reports all errors back properly.<\/p>\n<\/p><\/div>\n<\/div>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 7\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 8\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 9\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">10\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">11\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">12\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">13\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_put<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $local, $remote, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;   <span style=\"color:#75715e\"># Required argument order<\/span>\n\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};     <span style=\"color:#75715e\"># Enclose the password in the ENV hash<\/span>\n\n    $remote <span style=\"color:#f92672\">=<\/span> convert_path($remote);     <span style=\"color:#75715e\"># the remote file's variable<\/span>\n\n    <span style=\"color:#66d9ef\">my<\/span> ( undef, $dir, undef ) <span style=\"color:#f92672\">=<\/span> File::Spec<span style=\"color:#f92672\">-&gt;<\/span>splitpath($remote); <span style=\"color:#75715e\"># Make sure the full destination directory exists<\/span>\n    make_path($dir) <span style=\"color:#66d9ef\">unless<\/span> ( $dir <span style=\"color:#f92672\">and<\/span> <span style=\"color:#f92672\">-<\/span>d $dir );\n\n    copy( $local, $remote ); <span style=\"color:#75715e\"># copy the local file to the remote file<\/span>\n    <span style=\"color:#66d9ef\">return<\/span>;\n}<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<h3 id=\"the-get-function\">The get function<\/h3>\n<p>The <code>get<\/code> function directs the script to download or retrieve a local file from a remote destination. This function works similarly to the FTP <code>get<\/code> command.<\/p>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">7\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">8\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_get<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $remote, $local, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n    $remote <span style=\"color:#f92672\">=<\/span> convert_path($remote);\n\n    copy( $remote, $local );\n    <span style=\"color:#66d9ef\">return<\/span>;\n}<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<h3 id=\"the-ls-function\">The ls function<\/h3>\n<p>The <code>ls<\/code> function pulls the listing of a remote file or directory, similar to FTP or a local <code>ls<\/code> argument on the command line.<\/p>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 7\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 8\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 9\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">10\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">11\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">12\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">13\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">14\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">15\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_ls<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $path <span style=\"color:#f92672\">=<\/span> convert_path($path);\n\n    <span style=\"color:#66d9ef\">my<\/span> $ls <span style=\"color:#f92672\">=<\/span> <span style=\"color:#e6db74\">`ls -al $path`<\/span>;\n\n    <span style=\"color:#75715e\"># Remove the annoying 'total' line<\/span>\n    $ls <span style=\"color:#f92672\">=~<\/span> s<span style=\"color:#f92672\">|^<\/span>total[<span style=\"color:#f92672\">^<\/span>n]<span style=\"color:#f92672\">*<\/span>n<span style=\"color:#f92672\">||<\/span>;\n\n    <span style=\"color:#66d9ef\">print<\/span> $ls;\n    <span style=\"color:#66d9ef\">return<\/span>;\n}<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<h3 id=\"the-mkdir-function\">The mkdir function<\/h3>\n<p>The <code>mkdir<\/code> function ensures that a directory exists on the remote machine and that the system uploads the backup to a real path.<\/p>\n<div class=\"callout callout-info\">\n<div class=\"callout-heading\">Note:<\/div>\n<div class=\"callout-content\">\n<p>Not all transports use a feature like the <code>mkdir<\/code> function, however, you must include this function in the script.<\/p>\n<\/p><\/div>\n<\/div>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 7\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 8\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 9\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">10\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">11\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">12\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_mkdir<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $recurse, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $path <span style=\"color:#f92672\">=<\/span> convert_path($path);\n\n    make_path($path);\n\n    die <span style=\"color:#e6db74\">\"Failed to create $path\"<\/span> <span style=\"color:#66d9ef\">unless<\/span> <span style=\"color:#f92672\">-<\/span>d $path;\n    <span style=\"color:#66d9ef\">return<\/span>;\n}<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<h3 id=\"the-chdir-function\">The chdir function<\/h3>\n<p>The <code>chdir<\/code> function allows you to store the working directory and keep the session information between operations.<\/p>\n<div class=\"callout callout-info\">\n<div class=\"callout-heading\">Note:<\/div>\n<div class=\"callout-content\">\n<p>Because this is a custom transport script, the system will <strong>not<\/strong> keep session information between operations by a single active process.<\/p>\n<\/p><\/div>\n<\/div>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 7\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 8\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 9\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">10\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_chdir<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $path <span style=\"color:#f92672\">=<\/span> convert_path($path);\n    chdir $path;\n\n    <span style=\"color:#66d9ef\">print<\/span> get_sub_directory( getcwd() ) <span style=\"color:#f92672\">.<\/span> <span style=\"color:#e6db74\">\"n\"<\/span>;\n    <span style=\"color:#66d9ef\">return<\/span>;\n}<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<h3 id=\"the-rmdir-function\">The rmdir function<\/h3>\n<p>The <code>rmdir<\/code> function removes a directory and recursively deletes everything below the given directory. Based on which transport you use, you may need to remove all the files and directories below the given directory before the system can execute this function.<\/p>\n<div class=\"callout callout-danger\">\n<div class=\"callout-heading\">Warning:<\/div>\n<div class=\"callout-content\">\n<p>We <strong>strongly<\/strong> recommend that you verify the path that you plan to recursively delete. If you pass the root (<code>\/<\/code>) directory as the path to delete, your system will experience serious issues.<\/p>\n<\/p><\/div>\n<\/div>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 7\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 8\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 9\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">10\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">11\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">12\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_rmdir<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $path <span style=\"color:#f92672\">=<\/span> convert_path($path);\n\n    remove_tree($path);\n\n    die <span style=\"color:#e6db74\">\"$path still exists\"<\/span> <span style=\"color:#66d9ef\">if<\/span> <span style=\"color:#f92672\">-<\/span>d $path;\n    <span style=\"color:#66d9ef\">return<\/span>;\n}<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<h3 id=\"the-delete-function\">The delete function<\/h3>\n<p>The <code>delete<\/code> function deletes a single file.<\/p>\n<div class=\"callout callout-info\">\n<div class=\"callout-heading\">Note:<\/div>\n<div class=\"callout-content\">\n<p>We <strong>strongly<\/strong> recommend that you ensure the path that you use, relative or full, is appropriate for the transport. If your transport does <strong>not<\/strong> provide an error status check, use the <code>ls<\/code> function on the file to ensure the system deleted it.<\/p>\n<\/p><\/div>\n<\/div>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 7\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 8\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"> 9\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">10\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_delete<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> ( $path, $host, $user ) <span style=\"color:#f92672\">=<\/span> @_;\n\n    <span style=\"color:#66d9ef\">my<\/span> $password <span style=\"color:#f92672\">=<\/span> $ENV{<span style=\"color:#e6db74\">'PASSWORD'<\/span>};\n\n    $path <span style=\"color:#f92672\">=<\/span> convert_path($path);\n\n    unlink $path;\n    <span style=\"color:#66d9ef\">return<\/span>;\n}<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<h3 id=\"basic-error-check\">Basic error check<\/h3>\n<div class=\"callout callout-info\">\n<div class=\"callout-heading\">Note:<\/div>\n<div class=\"callout-content\">\n<p>We <strong>strongly<\/strong> recommend that you:<\/p>\n<ul>\n<li>Perform a basic error check to ensure that the script receives the proper arguments when the system calls it. At a minimum, you <strong>must<\/strong> pass the <code>usage() if ( @ARGV &lt; 2 )<\/code> command.<\/li>\n<li>Construct a built-in description of what the script is, what it does, and its purpose so that you can identify the script.<\/li>\n<\/ul><\/div>\n<\/div>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">my_delete<\/span> {\nusage() <span style=\"color:#66d9ef\">if<\/span> ( @ARGV <span style=\"color:#f92672\">&lt;<\/span> <span style=\"color:#ae81ff\">2<\/span> );<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<div class=\"highlight\">\n<div style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\">\n<table style=\"border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;\">\n<tr>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">1\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">2\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">3\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">4\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">5\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">6\n<\/span><span style=\"margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\">7\n<\/span><\/code><\/pre>\n<\/td>\n<td style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\"><span style=\"color:#66d9ef\">sub<\/span> <span style=\"color:#a6e22e\">usage<\/span> {\n    <span style=\"color:#66d9ef\">my<\/span> @cmds <span style=\"color:#f92672\">=<\/span> sort keys %commands;\n    <span style=\"color:#66d9ef\">print<\/span> STDERR <span style=\"color:#e6db74\">\"This script is for implementing a custom backup destinationn\"<\/span>;\n    <span style=\"color:#66d9ef\">print<\/span> STDERR <span style=\"color:#e6db74\">\"It requires the following arguments:  cmd, local_dir, cmd_argsn\"<\/span>;\n    <span style=\"color:#66d9ef\">print<\/span> STDERR <span style=\"color:#e6db74\">\"These are the valid commands:  @cmdsn\"<\/span>;\n    exit <span style=\"color:#ae81ff\">1<\/span>;\n}<\/code><\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<h3 id=\"the-cmd-command\">The $cmd command<\/h3>\n<p>Use the <code>%command<\/code> hash to call each command\u2019s specific code block.<\/p>\n<div class=\"highlight\">\n<pre style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-perl\" data-lang=\"perl\">$commands{$cmd}<span style=\"color:#f92672\">-&gt;<\/span>(@args);<\/code><\/pre>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Valid for versions 82 through the latest version Version: 82 Overview Warning: Only advanced users should create custom transport scripts. Other users can try one of WHM\u2019s other options: A local directory Amazon S3\u2122 Backblaze B2 FTP Google Drive\u2122 Rsync S3 Compatible SFTP WebDAV The Backup Configuration feature allows users to create a custom destination &hellip;<\/p>\n","protected":false},"author":1,"featured_media":227,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/ssdsunucum.com\/blog\/wp-json\/wp\/v2\/posts\/226"}],"collection":[{"href":"https:\/\/ssdsunucum.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ssdsunucum.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ssdsunucum.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ssdsunucum.com\/blog\/wp-json\/wp\/v2\/comments?post=226"}],"version-history":[{"count":0,"href":"https:\/\/ssdsunucum.com\/blog\/wp-json\/wp\/v2\/posts\/226\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ssdsunucum.com\/blog\/wp-json\/wp\/v2\/media\/227"}],"wp:attachment":[{"href":"https:\/\/ssdsunucum.com\/blog\/wp-json\/wp\/v2\/media?parent=226"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ssdsunucum.com\/blog\/wp-json\/wp\/v2\/categories?post=226"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ssdsunucum.com\/blog\/wp-json\/wp\/v2\/tags?post=226"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}