char *string_replace_percents( const char *str, const char *replace ) { /* Common case: do nothing if no percents. */ if(!strchr(str,'%')) return xxstrdup(str); buffer_t buffer; buffer_init(&buffer); const char *s; for(s=str;*s;s++) { if(*s=='%' && *(s+1)=='%' ) { if( *(s+2)=='%' && *(s+3)=='%') { buffer_putlstring(&buffer,"%%",2); s+=3; } else { buffer_putstring(&buffer,replace); s++; } } else { buffer_putlstring(&buffer,s,1); } } char *result; buffer_dup(&buffer,&result); buffer_free(&buffer); return result; }
int64_t copy_stream_to_buffer(FILE *input, char **buffer, size_t *len) { size_t _len; if (len == NULL) len = &_len; int64_t total = 0; buffer_t B; buffer_init(&B); while(1) { char buffer[COPY_BUFFER_SIZE]; int64_t actual_read = full_fread(input, buffer, COPY_BUFFER_SIZE); if(actual_read <= 0) { if (total == 0) return -1; else break; } if (buffer_putlstring(&B, buffer, actual_read) == -1) { buffer_free(&B); return -1; } total += actual_read; } buffer_dupl(&B, buffer, len); buffer_free(&B); return total; }
int cfs_freadall(CHIRP_FILE * f, buffer_t *B) { size_t n; char buf[BUFSIZ]; while ((n = cfs_fread(buf, sizeof(char), sizeof(buf), f)) > 0) { buffer_putlstring(B, buf, n); } return cfs_ferror(f) ? 0 : 1; }
static INT64_T chirp_fs_confuga_open (const char *path, INT64_T flags, INT64_T mode) { int rc; char *data = NULL; int fd = getfd(); strncpy(open_files[fd].path, path, sizeof(open_files[fd].path)-1); switch (flags & O_ACCMODE) { case O_RDONLY: if (strncmp(path_basename(path), ".__", 3) == 0) { size_t len; buffer_init(&open_files[fd].f.metadata); CATCH(confuga_metadata_lookup(C, path, &data, &len)); CATCHUNIX(buffer_putlstring(&open_files[fd].f.metadata, data, len)); open_files[fd].type = CHIRP_FS_CONFUGA_META_READ; } else { confuga_fid_t fid; CATCH_CONFUGA(confuga_lookup(C, path, &fid, NULL)); CATCH_CONFUGA(confuga_replica_open(C, fid, &open_files[fd].f.replica, STOPTIME)); open_files[fd].type = CHIRP_FS_CONFUGA_REPL_READ; } break; case O_WRONLY: if (strncmp(path_basename(path), ".__", 3) == 0) { buffer_init(&open_files[fd].f.metadata); open_files[fd].type = CHIRP_FS_CONFUGA_META_WRITE; } else { CATCH_CONFUGA(confuga_file_create(C, &open_files[fd].f.file.file, STOPTIME)); open_files[fd].f.file.size = 0; open_files[fd].f.file.flags = 0; if (flags & O_EXCL) open_files[fd].f.file.flags |= CONFUGA_O_EXCL; open_files[fd].type = CHIRP_FS_CONFUGA_FILE_WRITE; } break; case O_RDWR: CATCH(EINVAL); default: assert(0); } rc = 0; goto out; out: free(data); if (rc) return (errno = rc, -1); else return fd; /* N.B. return fd on success */ }
/* * Based on opengroup.org's definition of the Shell Command Language (also gnu's) * In section 2.2.3 on Double-Quoted Strings, it indicates you only need to * escape dollar sign, backtick, and backslash. I also escape double quote as * we are adding and exterior double quote around the string. * * [ $ \ ` " ] Are always escaped. * */ char *string_escape_shell( const char *str ) { buffer_t B[1]; buffer_init(B); buffer_abortonfailure(B, 1); const char *s; buffer_putliteral(B,"\""); for(s=str;*s;s++) { if(*s=='"' || *s=='\\' || *s=='$' || *s=='`') buffer_putliteral(B,"\\"); buffer_putlstring(B,s,1); } buffer_putliteral(B,"\""); char *result; buffer_dup(B,&result); buffer_free(B); return result; }
static INT64_T chirp_fs_confuga_pwrite(int fd, const void *buffer, INT64_T length, INT64_T offset) { int rc; size_t n; SETUP_FILE if (length < 0 || offset < 0) CATCH(EINVAL); switch (open_files[fd].type) { case CHIRP_FS_CONFUGA_FILE_WRITE: { if ((confuga_off_t)offset != open_files[fd].f.file.size) CATCH(EINVAL); /* do not allow random writes */ CATCH_CONFUGA(confuga_file_write(open_files[fd].f.file.file, buffer, length, &n, STOPTIME)); open_files[fd].f.file.size += n; break; } case CHIRP_FS_CONFUGA_META_WRITE: if ((size_t)offset != buffer_pos(&open_files[fd].f.metadata)) CATCH(EINVAL); /* do not allow random writes */ CATCHUNIX(buffer_putlstring(&open_files[fd].f.metadata, buffer, length)); n = length; break; default: CATCH(EBADF); } rc = 0; goto out; out: if (rc) { return (errno = rc, -1); } else { return n; /* N.B. return n on success */ } }
ssize_t link_stream_to_buffer(struct link * link, char **buffer, time_t stoptime) { ssize_t total = 0; buffer_t B; buffer_init(&B); while(1) { char buf[1<<16]; ssize_t actual = link_read(link, buf, sizeof(buf), stoptime); if(actual <= 0) break; if (buffer_putlstring(&B, buf, actual) == -1) { buffer_free(&B); return -1; } total += actual; } if (buffer_dup(&B, buffer) == -1) total = -1; buffer_free(&B); return total; }
int shellcode(const char *cmd, const char * const env[], const char *input, size_t len, buffer_t *Bout, buffer_t *Berr, int *status) { int rc; int in[2] = {-1, -1}; int out[2] = {-1, -1}; int err[2] = {-1, -1}; pid_t child = 0; const char * const _env[] = {NULL}; struct timeval start, stop; gettimeofday(&start, NULL); if (env == NULL) env = _env; CATCHUNIX(pipe(in)); CATCHUNIX(pipe(out)); CATCHUNIX(pipe(err)); CATCHUNIX(child = fork()); if(child == 0) { return execute(cmd, env, in, out, err); } CATCHUNIX(close(in[0])); in[0] = -1; CATCHUNIX(close(out[1])); out[1] = -1; CATCHUNIX(close(err[1])); err[1] = -1; CATCHUNIX(fcntl(in[1], F_GETFL)); CATCHUNIX(fcntl(in[1], F_SETFL, rc|O_NONBLOCK)); CATCHUNIX(fcntl(out[0], F_GETFL)); CATCHUNIX(fcntl(out[0], F_SETFL, rc|O_NONBLOCK)); CATCHUNIX(fcntl(err[0], F_GETFL)); CATCHUNIX(fcntl(err[0], F_SETFL, rc|O_NONBLOCK)); while (1) { char b[1<<16]; pid_t w; ssize_t result; CATCHUNIX(w = waitpid(child, status, WNOHANG)); if (len) { result = write(in[1], input, len); if (result == -1 && errno != EAGAIN && errno != EINTR) { CATCH(errno); } else if (result > 0) { input += result; len -= (size_t)result; } } else if (in[1] >= 0) { close(in[1]); in[1] = -1; } result = read(out[0], b, sizeof(b)); if (result == -1 && errno != EAGAIN && errno != EINTR) { CATCH(errno); } else if (result > 0 && Bout) { buffer_putlstring(Bout, b, (size_t)result); } result = read(err[0], b, sizeof(b)); if (result == -1 && errno != EAGAIN && errno != EINTR) { CATCH(errno); } else if (result > 0 && Berr) { buffer_putlstring(Berr, b, (size_t)result); } if (w == child) break; } child = 0; rc = 0; goto out; out: if (child > 0) { kill(child, SIGKILL); waitpid(child, NULL, 0); } if (in[0] >= 0) close(in[0]); if (in[1] >= 0) close(in[1]); if (out[0] >= 0) close(out[0]); if (out[1] >= 0) close(out[1]); if (err[0] >= 0) close(err[0]); if (err[1] >= 0) close(err[1]); gettimeofday(&stop, NULL); debug(D_DEBUG, "shellcode finished in %.2fs", (double)(stop.tv_sec-start.tv_sec) + (stop.tv_usec-start.tv_usec)*1e-6); return RCUNIX(rc); }