[BACK]Return to fargs.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / rsync

Annotation of src/usr.bin/rsync/fargs.c, Revision 1.13

1.13    ! benno       1: /*     $Id: fargs.c,v 1.12 2019/02/16 10:48:05 florian Exp $ */
1.1       benno       2: /*
                      3:  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17: #include <sys/stat.h>
                     18:
                     19: #include <assert.h>
                     20: #include <stdint.h>
                     21: #include <stdlib.h>
1.9       deraadt    22: #include <string.h>
1.1       benno      23:
                     24: #include "extern.h"
                     25:
1.2       benno      26: #define        RSYNC_PATH      "rsync"
1.1       benno      27:
                     28: char **
                     29: fargs_cmdline(struct sess *sess, const struct fargs *f)
                     30: {
1.9       deraadt    31:        char            **args = NULL, **new;
                     32:        size_t            i = 0, n = 1, j, argsz = 0;
1.11      florian    33:        char             *rsync_path, *ap;
1.1       benno      34:
1.3       deraadt    35:        assert(f != NULL);
1.1       benno      36:        assert(f->sourcesz > 0);
                     37:
1.3       deraadt    38:        if ((rsync_path = sess->opts->rsync_path) == NULL)
1.1       benno      39:                rsync_path = RSYNC_PATH;
                     40:
                     41:        /* Be explicit with array size. */
                     42:
1.2       benno      43:        argsz += 1;     /* dot separator */
                     44:        argsz += 1;     /* sink file */
                     45:        argsz += 5;     /* per-mode maximum */
1.13    ! benno      46:        argsz += 15;    /* shared args */
1.1       benno      47:        argsz += 1;     /* NULL pointer */
                     48:        argsz += f->sourcesz;
                     49:
                     50:        args = calloc(argsz, sizeof(char *));
1.9       deraadt    51:        if (args == NULL)
                     52:                goto out;
1.1       benno      53:
1.3       deraadt    54:        if (f->host != NULL) {
                     55:                assert(f->host != NULL);
1.8       benno      56:
1.11      florian    57:                /*
                     58:                 * Splice arguments from -e "foo bar baz" into array
                     59:                 * elements required for execve(2).
                     60:                 * This doesn't do anything fancy: it splits along
                     61:                 * whitespace into the array.
                     62:                 */
                     63:
1.9       deraadt    64:                if (sess->opts->ssh_prog) {
1.11      florian    65:                        ap = strdup(sess->opts->ssh_prog);
1.9       deraadt    66:                        if (ap == NULL)
                     67:                                goto out;
1.11      florian    68:
1.9       deraadt    69:                        while ((args[i] = strsep(&ap, " \t")) != NULL) {
                     70:                                if (args[i][0] == '\0') {
                     71:                                        ap++;   /* skip seperators */
                     72:                                        continue;
                     73:                                }
                     74:
                     75:                                /* Grow command-area of array */
1.11      florian    76:
1.9       deraadt    77:                                if (i++ < n)
                     78:                                        continue;
                     79:                                n += 10;
1.11      florian    80:                                new = reallocarray(args,
                     81:                                        argsz + n, sizeof(char *));
1.9       deraadt    82:                                if (new == NULL)
                     83:                                        goto out;
                     84:                                args = new;
                     85:                                argsz += n;
                     86:                        }
                     87:                } else
                     88:                        args[i++] = "ssh";
1.11      florian    89:
1.1       benno      90:                args[i++] = f->host;
1.5       deraadt    91:                args[i++] = rsync_path;
1.1       benno      92:                args[i++] = "--server";
1.3       deraadt    93:                if (f->mode == FARGS_RECEIVER)
1.1       benno      94:                        args[i++] = "--sender";
                     95:        } else {
1.5       deraadt    96:                args[i++] = rsync_path;
1.1       benno      97:                args[i++] = "--server";
                     98:        }
                     99:
                    100:        /* Shared arguments. */
                    101:
1.7       benno     102:        if (sess->opts->del)
                    103:                args[i++] = "--delete";
1.13    ! benno     104:        if (sess->opts->numeric_ids)
        !           105:                args[i++] = "--numeric-ids";
1.7       benno     106:        if (sess->opts->preserve_gids)
                    107:                args[i++] = "-g";
                    108:        if (sess->opts->preserve_links)
                    109:                args[i++] = "-l";
                    110:        if (sess->opts->dry_run)
                    111:                args[i++] = "-n";
1.10      florian   112:        if (sess->opts->preserve_uids)
                    113:                args[i++] = "-o";
1.7       benno     114:        if (sess->opts->preserve_perms)
                    115:                args[i++] = "-p";
1.12      florian   116:        if (sess->opts->devices)
                    117:                args[i++] = "-D";
1.7       benno     118:        if (sess->opts->recursive)
                    119:                args[i++] = "-r";
                    120:        if (sess->opts->preserve_times)
                    121:                args[i++] = "-t";
1.1       benno     122:        if (sess->opts->verbose > 3)
                    123:                args[i++] = "-v";
                    124:        if (sess->opts->verbose > 2)
                    125:                args[i++] = "-v";
                    126:        if (sess->opts->verbose > 1)
                    127:                args[i++] = "-v";
                    128:        if (sess->opts->verbose > 0)
                    129:                args[i++] = "-v";
1.12      florian   130:        if (sess->opts->specials && !sess->opts->devices)
                    131:                args[i++] = "--specials";
                    132:        if (!sess->opts->specials && sess->opts->devices)
                    133:                /* --devices is sent as -D --no-specials */
                    134:                args[i++] = "--no-specials";
1.1       benno     135:
                    136:        /* Terminate with a full-stop for reasons unknown. */
                    137:
                    138:        args[i++] = ".";
                    139:
1.3       deraadt   140:        if (f->mode == FARGS_RECEIVER) {
1.1       benno     141:                for (j = 0; j < f->sourcesz; j++)
                    142:                        args[i++] = f->sources[j];
                    143:        } else
                    144:                args[i++] = f->sink;
                    145:
                    146:        args[i] = NULL;
                    147:        return args;
1.9       deraadt   148: out:
                    149:        free(args);
                    150:        ERR(sess, "calloc");
                    151:        return NULL;
1.1       benno     152: }