Skip to content

Instantly share code, notes, and snippets.

@DanBUK
Created March 6, 2013 07:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanBUK/5097509 to your computer and use it in GitHub Desktop.
Save DanBUK/5097509 to your computer and use it in GitHub Desktop.
rsync wrapper
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#define CONF_FILE "/etc/rsync_secure.conf"
typedef struct {
int length;
char * value;
} len_str;
typedef struct {
int length;
len_str ** values;
} str_array;
typedef struct {
struct map_t *nxt;
char *name;
char *value;
} map_t;
map_t *map_create() {
map_t *m;
m=(map_t *)malloc(sizeof(map_t));
m->name=NULL;
m->value=NULL;
m->nxt=NULL;
}
void map_set(map_t *m,char *name,char *value) {
map_t *map;
if(m->name==NULL) {
m->name=(char *)malloc(strlen(name)+1);
strcpy(m->name,name);
m->value=(char *)malloc(strlen(value)+1);
strcpy(m->value,value);
m->nxt=NULL;
return;
}
for(map=m;;map=(map_t *)map->nxt) {
if(!strcasecmp(name,map->name)) {
if(map->value!=NULL) {
free(map->value);
map->value=(char *)malloc(strlen(value)+1);
strcpy(map->value,value);
return;
}
}
if(map->nxt==NULL) {
map->nxt=(struct map_t *)malloc(sizeof(map_t));
map=(map_t *)map->nxt;
map->name=(char *)malloc(strlen(name)+1);
strcpy(map->name,name);
map->value=(char *)malloc(strlen(value)+1);
strcpy(map->value,value);
map->nxt=NULL;
return;
}
}
}
char *map_get(map_t *m,char *name) {
map_t *map;
for(map=m;map!=NULL;map=(map_t *)map->nxt) {
if(!strcasecmp(name,map->name)) {
return map->value;
}
}
return "";
}
str_array * init_str_array () {
str_array *rv = malloc(sizeof(str_array));
rv->length = 0;
rv->values = (len_str **)malloc(12);
return rv;
}
void str_split (str_array *rv, char *str, char* token) {
char *tmpstr;
char *part;
len_str *item;
size_t inlen = strlen(str);
int c = 0;
tmpstr = (char *)malloc(inlen + 1);
strncpy(tmpstr, str, inlen);
part = strtok(tmpstr, token);
while (part) {
rv->length++;
rv->values = (len_str **)realloc(rv->values, sizeof(len_str *) * rv->length);
item = (len_str *)malloc(sizeof(len_str *));
item->length = strlen(part);
item->value = malloc(sizeof(char) * (item->length + 1));
strncpy(item->value, part, item->length);
rv->values[c] = item;
c++;
part = strtok(NULL, token);
}
}
char ** str_split_two (char *str, char *token) {
char **rv[2];
char *tmpstr;
char *part;
tmpstr = malloc(sizeof(char) * (strlen(str) + 1));
strcpy(tmpstr, str);
part = strtok(tmpstr, token);
if (part != NULL) {
rv[0] = malloc(sizeof(char) * (strlen(part) + 1));
strcpy(rv[0], part);
part = strtok(NULL, token);
if (part != NULL) {
rv[1] = malloc(sizeof(char) * (strlen(part) + 1));
strcpy(rv[1], part);
return rv;
} else {
return NULL;
}
} else {
return NULL;
}
}
char * get_username () {
struct passwd *uinfo = getpwuid(getuid());
char * rv;
int len = strlen(uinfo->pw_name);
run_user = malloc(sizeof(char) * (len + 1));
strncpy(rv, uinfo->pw_name, len);
rv[len] = 0;
return rv;
}
char * read_file (char * file_path) {
char *buffer;
int len;
int rv;
FILE *fh = fopen(file_path, "rb");
if (fh) {
rv = fseek(fh, 0, SEEK_END);
if (rv == 0) {
len = ftell(fh);
fseek(fh, 0, SEEK_SET);
buffer = malloc(sizeof(char) * (len + 1));
if (buffer) {
rv = fread(buffer, 1, len, fh);
fclose(fh);
if (rv > 0) {
return buffer;
} else {
return NULL;
}
} else {
fclose(fh);
return NULL;
}
} else {
fclose(fh);
return NULL;
}
} else {
return NULL;
}
}
void setup_config (map_t *config, char *buffer) {
int i;
char **prts;
str_array *conflines = init_str_array();
str_split(conflines, buffer, "\n");
if (conflines->length > 0) {
while(i < conflines->length) {
prts = str_split_two(conflines->values[i]->length, "=");
if (prts != NULL) {
map_set(config, prts[0], prts[1])
}
i++;
}
}
}
int main(int argc, char *argv[]) {
int last = argc - 1;
char * run_user = get_username();
char * tar_path;
char **prts;
tar_path = malloc(sizeof(char) * (strlen(argv[last]) + 1));
strcpy(tar_path, argv[last]);
str_array *conflines = init_str_array();
char *buffer = 0;
long length;
int rv;
char command[1025];
buffer = read_file(CONF_FILE);
if (buffer) {
userpaths = map_create();
setup_config(userpaths, buffer);
buffer = map_get(userpaths, run_user);
if(strlen(buffer) > 0) {
str_array *validpaths = init_str_array();
str_split(validpaths, buffer, ",");
if (validpaths->length > 0) {
rv = 0;
while(rv < validpaths->length) {
if(strcasecmp(tar_path, validpaths->values[rv]->value) == 0) {
// TODO - Sanitize argv[(last - 2)] to only be -[a-Z0-9]
snprintf(command, 1024, "/usr/bin/rsync --server %s . %s", argv[(last - 2)], tar_path);
system(command);
}
rv++;
}
return 0;
} else {
fprintf(stderr, "Error: No paths found [2].\n");
return 5;
}
} else {
fprintf(stderr, "Error: No paths found [1].\n");
return 4;
}
} else {
fprintf(stderr, "Error: Cannot read config file.\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment