void client_loop(int client_fd, char *client_ip) { int ret; char pwd[1024]; char buffer[BUFFER_SIZE]; if ((getcwd(pwd, 1024)) == NULL) exit_write("Error : getcwd failed\n"); memset(buffer, 0, BUFFER_SIZE); handle_client(client_fd); while ((ret = read(client_fd, buffer, BUFFER_SIZE - 1)) > 0) { buffer[ret - 1] = '\0'; safe_write(STDOUT, "[Server]> Get command : "); safe_write(STDOUT, buffer); safe_write(STDOUT, "\n"); exec_command(buffer, client_fd, client_ip, pwd); memset(buffer, 0, BUFFER_SIZE); } xclose(client_fd); exit(EXIT_SUCCESS); }
pid_t my_fork_pty(int *fd_amaster, int *fd_aslave, char *tty_name) { pid_t pid; my_open_pty(fd_amaster, fd_aslave, tty_name); if ((pid = fork()) < 0) { errno = EAGAIN; my_exit_perror("fork"); } else if (pid == 0) { my_login_tty(fd_aslave); return (0); } else { xclose(*fd_aslave); return (pid); } return (-1); }
int init_history(t_glob *glob) { int fd; char **tabl; int i; i = 0; glob->hist = NULL; fd = open_configfile(HISTORY_NAME, O_RDONLY, 0); if (fd != -1) { tabl = read_all(fd); while (tabl && tabl[i]) { if (add_hist_end(glob, tabl[i++])) return (0); } free_wtb(tabl); } xclose(fd); return (1); }
void comm_main(void) { int file[2]; char *line[2]; int i; if (toys.optflags == 7) return; for (i = 0; i < 2; i++) { file[i] = xopenro(toys.optargs[i]); line[i] = get_line(file[i]); } while (line[0] && line[1]) { int order = strcmp(line[0], line[1]); if (order == 0) { writeline(line[0], 2); for (i = 0; i < 2; i++) { free(line[i]); line[i] = get_line(file[i]); } } else { i = order < 0 ? 0 : 1; writeline(line[i], i); free(line[i]); line[i] = get_line(file[i]); } } /* print rest of the longer file */ for (i = line[0] ? 0 : 1; line[i];) { writeline(line[i], i); free(line[i]); line[i] = get_line(file[i]); } if (CFG_TOYBOX_FREE) for (i = 0; i < 2; i++) xclose(file[i]); }
Boolean PosixStorageObject::suspend() { if (fd_ < 0 || suspended_) return 0; struct stat sb; if (fstat(fd_, &sb) < 0 || !S_ISREG(sb.st_mode)) return 0; suspendFailedMessage_ = 0; suspendPos_ = lseek(fd_, 0, SEEK_CUR); if (suspendPos_ == (off_t)-1) { suspendFailedMessage_ = &PosixStorageMessages::lseekSystemCall; suspendErrno_ = errno; } if (xclose(fd_) < 0 && !suspendFailedMessage_) { suspendFailedMessage_ = &PosixStorageMessages::closeSystemCall; suspendErrno_ = errno; } fd_ = -1; suspended_ = 1; releaseD(); return 1; }
void list_file(struct s_static_client *br) { ssize_t octet; char buffer[BUF_SIZE]; char message[CMD]; if (get_dataconnection_port(br) == -1) return ; xwrite(br->s_fd, "LIST", 4); if (try_to_connect(br) == -1) return ; show_response_complete(message, br); my_putstr("\n"); while ((octet = recv(br->pasv, buffer, BUF_SIZE, 0)) > 0) xwrite(1, buffer, octet); my_putstr("\n"); if (octet == -1) my_putstr("ERROR : Error during data transfer\n"); xclose(br->pasv); br->retrieve = -1; br->pasv = -1; }
int exec_redir(t_cmd *cmd, int i) { char *buffer; buffer = xcalloc(4096, sizeof(*buffer)); if (cmd[i].type == 1) { if (strcmp(cmd[i - 1].token, "<<") == 0) remove(cmd[i].args[0]); else if (cmd[i].type == 1 && cmd[i - 1].type == 1) { if ((strcmp(cmd[i - 1].token, ">") == 0) || (strcmp(cmd[i - 1].token, ">>") == 0)) { xread(cmd[i - 1].fdout, buffer, 4095); write(cmd[i].fdin, buffer, (strlen(buffer) + 1)); xclose(cmd[i - 1].fdout); return (1); } } } return (0); }
static void xclient (const char *pf) { int sfd, i; int64_t nbytes; char buf[1024] = {}; char *ubuf; char host[1024] = {}; sprintf (host, "%s%s", pf, "://127.0.0.1:18897"); randstr (buf, 1024); BUG_ON ( (sfd = xconnect (host) ) < 0); for (i = 0; i < cnt; i++) { nbytes = rand() % 1024; ubuf = ubuf_alloc (nbytes); memcpy (ubuf, buf, nbytes); BUG_ON (0 != xsend (sfd, ubuf) ); BUG_ON (0 != xrecv (sfd, &ubuf) ); DEBUG_OFF ("%d recv response", sfd); assert (memcmp (ubuf, buf, nbytes) == 0); ubuf_free (ubuf); } xclose (sfd); }
/* Get_Default_Cache() * ====================================================================== */ void Get_Default_Cache( void ) { int out; int error; char Drive; long len; if( SpeedoFlag ) { /* Get the Bootup Device */ strcpy( ExtendPath, "C:\\EXTEND.SYS" ); Drive = GetBaseDrive(); ExtendPath[0] = Drive; olddma = Fgetdta(); Fsetdta(&newdma); /* Point to OUR buffer */ xopen( ExtendPath ); /* Find the extend.sys file and open it*/ if( !errno ) /* WE have an EXTEND.SYS and need to */ { /* look for the font path */ lookahead = NO_TOKEN; if( !match(PATH) ) { /* Error: No Path line at the top of the extend.sys file * Therefore, we don't load any default.fsm file. */ xclose(); Fsetdta(olddma); /* Point to OLD buffer */ return; } skipequal(); if( match(PATHSPEC) ) { strncpy( OutlinePath, yytext, yyleng ); len = yyleng-1; if( OutlinePath[len] != '\\' ) ++len; OutlinePath[len] = '\0'; if( len > 2 ) /* below code fails for items like 'f:'*/ { if( !stat( OutlinePath, &statbuf) ) errno = (isdir(&statbuf)) ? 0 : ENOTDIR; if( errno ) { /* Error Parsing the path */ xclose(); Fsetdta(olddma); /* Point to OLD buffer */ return; } } } xclose(); Fsetdta(olddma); /* Point to OLD buffer */ strcat( OutlinePath, "\\DEFAULT.SPC" ); error = Fopen( OutlinePath, 0 ); if ( error < 0 ) /* No such files! */ return; Fclose( error ); /* Close the file immediately */ if( open_vwork() ) { out = v_loadcache( vhandle, OutlinePath, TRUE ); if( out == -1 ) /* Cache I/O Error! */ form_alert( 1, alert19 ); close_vwork(); } /* error opening a workstation, no cache loaded..*/ else form_alert( 1, alert18 ); }/* NO EXTEND.SYS, NO default cache */ } }
int patch_main(int argc UNUSED_PARAM, char **argv) { int opts; int reverse, state = 0; char *oldname = NULL, *newname = NULL; char *opt_p, *opt_i; long oldlen = oldlen; /* for compiler */ long newlen = newlen; /* for compiler */ INIT_TT(); opts = getopt32(argv, FLAG_STR, &opt_p, &opt_i); argv += optind; reverse = opts & FLAG_REVERSE; TT.prefix = (opts & FLAG_PATHLEN) ? xatoi(opt_p) : 0; // can be negative! TT.filein = TT.fileout = -1; if (opts & FLAG_INPUT) { xmove_fd(xopen_stdin(opt_i), STDIN_FILENO); } else { if (argv[0] && argv[1]) { xmove_fd(xopen_stdin(argv[1]), STDIN_FILENO); } } if (argv[0]) { oldname = xstrdup(argv[0]); newname = xstrdup(argv[0]); } // Loop through the lines in the patch for(;;) { char *patchline; patchline = xmalloc_fgetline(stdin); if (!patchline) break; // Other versions of patch accept damaged patches, // so we need to also. if (!*patchline) { free(patchline); patchline = xstrdup(" "); } // Are we assembling a hunk? if (state >= 2) { if (*patchline==' ' || *patchline=='+' || *patchline=='-') { dlist_add(&TT.current_hunk, patchline); if (*patchline != '+') oldlen--; if (*patchline != '-') newlen--; // Context line? if (*patchline==' ' && state==2) TT.context++; else state=3; // If we've consumed all expected hunk lines, apply the hunk. if (!oldlen && !newlen) state = apply_one_hunk(); continue; } fail_hunk(); state = 0; continue; } // Open a new file? if (!strncmp("--- ", patchline, 4) || !strncmp("+++ ", patchline, 4)) { char *s, **name = reverse ? &newname : &oldname; int i; if (*patchline == '+') { name = reverse ? &oldname : &newname; state = 1; } finish_oldfile(); if (!argv[0]) { free(*name); // Trim date from end of filename (if any). We don't care. for (s = patchline+4; *s && *s!='\t'; s++) if (*s=='\\' && s[1]) s++; i = atoi(s); if (i>1900 && i<=1970) *name = xstrdup("/dev/null"); else { *s = 0; *name = xstrdup(patchline+4); } } // We defer actually opening the file because svn produces broken // patches that don't signal they want to create a new file the // way the patch man page says, so you have to read the first hunk // and _guess_. // Start a new hunk? Usually @@ -oldline,oldlen +newline,newlen @@ // but a missing ,value means the value is 1. } else if (state == 1 && !strncmp("@@ -", patchline, 4)) { int i; char *s = patchline+4; // Read oldline[,oldlen] +newline[,newlen] TT.oldlen = oldlen = TT.newlen = newlen = 1; TT.oldline = strtol(s, &s, 10); if (*s == ',') TT.oldlen = oldlen = strtol(s+1, &s, 10); TT.newline = strtol(s+2, &s, 10); if (*s == ',') TT.newlen = newlen = strtol(s+1, &s, 10); if (oldlen < 1 && newlen < 1) bb_error_msg_and_die("Really? %s", patchline); TT.context = 0; state = 2; // If this is the first hunk, open the file. if (TT.filein == -1) { int oldsum, newsum, empty = 0; char *name; oldsum = TT.oldline + oldlen; newsum = TT.newline + newlen; name = reverse ? oldname : newname; // We're deleting oldname if new file is /dev/null (before -p) // or if new hunk is empty (zero context) after patching if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) { name = reverse ? newname : oldname; empty++; } // handle -p path truncation. for (i=0, s = name; *s;) { if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) break; if (*s++ != '/') continue; while (*s == '/') s++; i++; name = s; } if (empty) { // File is empty after the patches have been applied state = 0; if (option_mask32 & FLAG_RMEMPTY) { // If flag -E or --remove-empty-files is set printf("removing %s\n", name); xunlink(name); } else { printf("patching file %s\n", name); xclose(xopen(name, O_WRONLY | O_TRUNC)); } // If we've got a file to open, do so. } else if (!(option_mask32 & FLAG_PATHLEN) || i <= TT.prefix) { struct stat statbuf; // If the old file was null, we're creating a new one. if (!strcmp(oldname, "/dev/null") || !oldsum) { printf("creating %s\n", name); s = strrchr(name, '/'); if (s) { *s = 0; bb_make_directory(name, -1, FILEUTILS_RECUR); *s = '/'; } TT.filein = xopen(name, O_CREAT|O_EXCL|O_RDWR); } else { printf("patching file %s\n", name); TT.filein = xopen(name, O_RDONLY); } TT.tempname = xasprintf("%sXXXXXX", name); TT.fileout = xmkstemp(TT.tempname); // Set permissions of output file fstat(TT.filein, &statbuf); fchmod(TT.fileout, statbuf.st_mode); TT.linenum = 0; TT.hunknum = 0; } } TT.hunknum++; continue; } // If we didn't continue above, discard this line. free(patchline); } finish_oldfile(); if (ENABLE_FEATURE_CLEAN_UP) { free(oldname); free(newname); } return TT.exitval; }
int main(int ac, char **av, char **env) { char *hostname; int is_command = 0; int is_sftp = 0; create_hash(); if (ac == 3 && av[1] != NULL && av[2] != NULL && strcmp("-c", av[1]) == 0 && (strstr(av[2], "sftp-server") != NULL || strstr(av[2], "MySecureShell") != NULL)) is_sftp = 1; else if (ac >= 3 && av[1] != NULL && av[2] != NULL && strcmp("-c", av[1]) == 0) is_command = 1; else parse_args(ac, av); hostname = get_ip(0); (void) setenv("SSH_IP", hostname, 1); free(hostname); FileSpecInit(); load_config(0); if (is_sftp == 1) { tGlobal *params; char *ptr; int max, fd, sftp_version; hostname = get_ip(hash_get_int("ResolveIP")); if (hostname == NULL) { perror("unable to resolve ip"); exit(16); } params = calloc(1, sizeof(*params)); if (params == NULL) { perror("unable to alloc memory"); exit(15); } ptr = hash_get("Home"); params->home = strdup(ptr == NULL ? "{error home}" : ptr); ptr = hash_get("User"); params->user = strdup(ptr == NULL ? "{error user}" : ptr); params->ip = strdup(hostname == NULL ? "{error ip}" : hostname); params->portSource = get_port_client(); params->who = SftpWhoGetStruct(1); if (params->who != NULL) { params->who->time_begin = (u_int32_t) time(0); params->who->pid = (u_int32_t) getpid(); (void) strncat(params->who->home, params->home, sizeof(params->who->home) - 1); (void) strncat(params->who->user, params->user, sizeof(params->who->user) - 1); (void) strncat(params->who->ip, params->ip, sizeof(params->who->ip) - 1); } //check if the server is up and user is not admin if ((fd = open(SHUTDOWN_FILE, O_RDONLY)) >= 0) { xclose(fd); if (hash_get_int("IsAdmin") == 0 && hash_get_int("IsSimpleAdmin") == 0) { SftpWhoReleaseStruct(params->who); delete_hash(); FileSpecDestroy(); exit(0); } } max = hash_get_int("LogSyslog"); if (hash_get("LogFile") != NULL) mylog_open(strdup(hash_get("LogFile")), max); else mylog_open(strdup(MSS_LOG), max); if (params->who == NULL) { mylog_printf(MYLOG_ERROR, "[%s]Server '%s' reached maximum connexion (%i clients)", hash_get("User"), hash_get("SERVER_IP"), SFTPWHO_MAXCLIENT); SftpWhoReleaseStruct(NULL); delete_hash(); FileSpecDestroy(); mylog_close_and_free(); exit(14); } max = hash_get_int("LimitConnectionByUser"); if (max > 0 && count_program_for_uid(hash_get("User")) > max) { mylog_printf(MYLOG_ERROR, "[%s]Too many connection for this account", hash_get("User")); SftpWhoReleaseStruct(params->who); delete_hash(); FileSpecDestroy(); exit(10); } max = hash_get_int("LimitConnectionByIP"); if (max > 0 && count_program_for_ip(hostname) > max) { mylog_printf(MYLOG_ERROR, "[%s]Too many connection for this IP : %s", hash_get("User"), hostname); SftpWhoReleaseStruct(params->who); delete_hash(); FileSpecDestroy(); exit(11); } max = hash_get_int("LimitConnection"); if (max > 0 && count_program_for_uid(NULL) > max) { mylog_printf(MYLOG_ERROR, "[%s]Too many connection for the server : %s", hash_get("User"), hash_get("SERVER_IP")); SftpWhoReleaseStruct(params->who); delete_hash(); FileSpecDestroy(); exit(12); } if (hash_get_int("DisableAccount")) { mylog_printf(MYLOG_ERROR, "[%s]Account is closed", hash_get("User")); SftpWhoReleaseStruct(params->who); delete_hash(); FileSpecDestroy(); exit(13); } params->flagsGlobals |= (hash_get_int("StayAtHome") ? SFTPWHO_STAY_AT_HOME : 0) + (hash_get_int("VirtualChroot") ? SFTPWHO_VIRTUAL_CHROOT : 0) + (hash_get_int("ResolveIP") ? SFTPWHO_RESOLVE_IP : 0) + (hash_get_int("IgnoreHidden") ? SFTPWHO_IGNORE_HIDDEN : 0) + (hash_get_int("DirFakeUser") ? SFTPWHO_FAKE_USER : 0) + (hash_get_int("DirFakeGroup") ? SFTPWHO_FAKE_GROUP : 0) + (hash_get_int("DirFakeMode") ? SFTPWHO_FAKE_MODE : 0) + (hash_get_int("HideNoAccess") ? SFTPWHO_HIDE_NO_ACESS : 0) + (hash_get_int("ByPassGlobalDownload") ? SFTPWHO_BYPASS_GLB_DWN : 0) + (hash_get_int("ByPassGlobalUpload") ? SFTPWHO_BYPASS_GLB_UPL : 0) + (hash_get_int("ShowLinksAsLinks") ? SFTPWHO_LINKS_AS_LINKS : 0) + (hash_get_int("IsAdmin") ? SFTPWHO_IS_ADMIN : 0) + (hash_get_int("IsSimpleAdmin") ? SFTPWHO_IS_SIMPLE_ADMIN : 0) + (hash_get_int("CanChangeRights") ? SFTPWHO_CAN_CHG_RIGHTS : 0) + (hash_get_int("CanChangeTime") ? SFTPWHO_CAN_CHG_TIME : 0) + (hash_get_int("CreateHome") ? SFTPWHO_CREATE_HOME : 0); params->flagsDisable = (hash_get_int("DisableRemoveDir") ? SFTP_DISABLE_REMOVE_DIR : 0) + (hash_get_int("DisableRemoveFile") ? SFTP_DISABLE_REMOVE_FILE : 0) + (hash_get_int("DisableReadDir") ? SFTP_DISABLE_READ_DIR : 0) + (hash_get_int("DisableReadFile") ? SFTP_DISABLE_READ_FILE : 0) + (hash_get_int("DisableWriteFile") ? SFTP_DISABLE_WRITE_FILE : 0) + (hash_get_int("DisableSetAttribute") ? SFTP_DISABLE_SET_ATTRIBUTE : 0) + (hash_get_int("DisableMakeDir") ? SFTP_DISABLE_MAKE_DIR : 0) + (hash_get_int("DisableRename") ? SFTP_DISABLE_RENAME : 0) + (hash_get_int("DisableSymLink") ? SFTP_DISABLE_SYMLINK : 0) + (hash_get_int("DisableOverwrite") ? SFTP_DISABLE_OVERWRITE : 0) + (hash_get_int("DisableStatsFs") ? SFTP_DISABLE_STATSFS : 0); params->who->status |= params->flagsGlobals; _sftpglobal->download_max = (u_int32_t) hash_get_int("GlobalDownload"); _sftpglobal->upload_max = (u_int32_t) hash_get_int("GlobalUpload"); if (hash_get_int("Download") > 0) { params->download_max = (u_int32_t) hash_get_int("Download"); params->who->download_max = params->download_max; } if (hash_get_int("Upload") > 0) { params->upload_max = (u_int32_t) hash_get_int("Upload"); params->who->upload_max = params->upload_max; } if (hash_get_int("IdleTimeOut") > 0) params->who->time_maxidle = (u_int32_t) hash_get_int("IdleTimeOut"); if (hash_get_int("DirFakeMode") > 0) params->dir_mode = (u_int32_t) hash_get_int("DirFakeMode"); sftp_version = hash_get_int("SftpProtocol"); if (hash_get_int("ConnectionMaxLife") > 0) params->who->time_maxlife = (u_int32_t) hash_get_int("ConnectionMaxLife"); if (hash_get("ExpireDate") != NULL) { struct tm tm; time_t currentTime, maxTime; if (strptime((const char *) hash_get("ExpireDate"), "%Y-%m-%d %H:%M:%S", &tm) != NULL) { maxTime = mktime(&tm); currentTime = time(NULL); if (currentTime > maxTime) //time elapsed { mylog_printf(MYLOG_ERROR, "[%s]Account has expired : %s", hash_get("User"), hash_get("ExpireDate")); SftpWhoReleaseStruct(params->who); delete_hash(); mylog_close_and_free(); exit(15); } else { //check if expireDate < time_maxlife currentTime = maxTime - currentTime; if ((u_int32_t) currentTime < params->who->time_maxlife) params->who->time_maxlife = (u_int32_t) currentTime; } } DEBUG((MYLOG_DEBUG, "[%s][%s]ExpireDate time to rest: %i", params->who->user, params->who->ip, params->who->time_maxlife)); } if (hash_exists("MaxOpenFilesForUser") == MSS_TRUE) params->max_openfiles = hash_get_int("MaxOpenFilesForUser"); if (hash_exists("MaxReadFilesForUser") == MSS_TRUE) params->max_readfiles = hash_get_int("MaxReadFilesForUser"); if (hash_exists("MaxWriteFilesForUser") == MSS_TRUE) params->max_writefiles = hash_get_int("MaxWriteFilesForUser"); if (hash_get_int("MinimumRightsDirectory") > 0) params->minimum_rights_directory = hash_get_int( "MinimumRightsDirectory"); if (hash_get_int("MinimumRightsFile") > 0) params->minimum_rights_file = hash_get_int("MinimumRightsFile"); if (hash_get_int("MaximumRightsDirectory") > 0) params->maximum_rights_directory = hash_get_int( "MaximumRightsDirectory"); else params->maximum_rights_directory = 07777; if (hash_get_int("MaximumRightsFile") > 0) params->maximum_rights_file = hash_get_int("MaximumRightsFile"); else params->maximum_rights_file = 07777; if (hash_get_int("DefaultRightsDirectory") > 0) params->default_rights_directory = hash_get_int("DefaultRightsDirectory"); else params->default_rights_directory = 0755; if (hash_get_int("DefaultRightsFile") > 0) params->default_rights_file = hash_get_int("DefaultRightsFile"); else params->default_rights_file = 0644; if (hash_get_int("ForceRightsDirectory") > 0) { params->minimum_rights_directory = hash_get_int("ForceRightsDirectory"); params->maximum_rights_directory = params->minimum_rights_directory; } if (hash_get_int("ForceRightsFile") > 0) { params->minimum_rights_file = hash_get_int("ForceRightsFile"); params->maximum_rights_file = params->minimum_rights_file; } if (hash_get("ForceUser") != NULL) params->force_user = strdup(hash_get("ForceUser")); if (hash_get("ForceGroup") != NULL) params->force_group = strdup(hash_get("ForceGroup")); if (hash_get("Charset") != NULL) setCharset(hash_get("Charset")); if (hash_get("ApplyFileSpec") != NULL) FileSpecActiveProfils(hash_get("ApplyFileSpec"), 0); delete_hash(); if (hostname != NULL) free(hostname); params->current_user = getuid(); params->current_group = getgid(); return (SftpMain(params, sftp_version)); } else { char *ptr; if (getuid() != geteuid()) //if we are in utset byte mode then we restore user's rights to avoid security problems { if (seteuid(getuid()) == -1 || setegid(getgid()) == -1) { perror("revoke root rights"); exit(1); } } ptr = hash_get("Shell"); if (ptr != NULL) { if (strcmp(ptr, av[0]) != 0) { av[0] = ptr; if (is_command == 1) { size_t len = 0; char **new_env; char *cmd, *envVar; int i; for (i = 2; i < ac; i++) len += strlen(av[i]); cmd = malloc(len + ac + 1); envVar = malloc(len + ac + 1 + 21); cmd[0] = '\0'; for (i = 2; i < ac; i++) { if (i > 2) strcat(cmd, " "); strcat(cmd, av[i]); } av[2] = cmd; av[3] = NULL; strcpy(envVar, "SSH_ORIGINAL_COMMAND="); strcat(envVar, cmd); len = 0; for (i = 0; env[i] != NULL; i++) len++; new_env = calloc(len + 2, sizeof(*new_env)); for (i = 0; i < len; i++) new_env[i] = env[i]; new_env[len] = envVar; (void) execve(av[0], av, new_env); } else (void) execve(av[0], av, env); perror("execute shell"); } else (void) fprintf(stderr, "You cannot specify MySecureShell has shell (in the MySecureShell configuration) !"); } else (void) fprintf(stderr, "Shell access is disabled !"); exit(1); } }
/* Set ARCHIVE for uncompressing, then reading an archive. */ pid_t sys_child_open_for_uncompress (void) { int parent_pipe[2]; int child_pipe[2]; pid_t grandchild_pid; pid_t child_pid; xpipe (parent_pipe); child_pid = xfork (); if (child_pid > 0) { /* The parent tar is still here! Just clean up. */ archive = parent_pipe[PREAD]; xclose (parent_pipe[PWRITE]); return child_pid; } /* The newborn child tar is here! */ set_program_name (_("tar (child)")); signal (SIGPIPE, SIG_DFL); xdup2 (parent_pipe[PWRITE], STDOUT_FILENO); xclose (parent_pipe[PREAD]); /* Check if we need a grandchild tar. This happens only if either: a) we're reading stdin: to force unblocking; b) the file is to be accessed by rmt: compressor doesn't know how; c) the file is not a plain file. */ if (strcmp (archive_name_array[0], "-") != 0 && !_remdev (archive_name_array[0]) && is_regular_file (archive_name_array[0])) { /* We don't need a grandchild tar. Open the archive and lauch the uncompressor. */ archive = open (archive_name_array[0], O_RDONLY | O_BINARY, MODE_RW); if (archive < 0) open_fatal (archive_name_array[0]); xdup2 (archive, STDIN_FILENO); execlp (use_compress_program_option, use_compress_program_option, "-d", (char *) 0); exec_fatal (use_compress_program_option); } /* We do need a grandchild tar. */ xpipe (child_pipe); grandchild_pid = xfork (); if (grandchild_pid == 0) { /* The newborn grandchild tar is here! Launch the uncompressor. */ set_program_name (_("tar (grandchild)")); xdup2 (child_pipe[PREAD], STDIN_FILENO); xclose (child_pipe[PWRITE]); execlp (use_compress_program_option, use_compress_program_option, "-d", (char *) 0); exec_fatal (use_compress_program_option); } /* The child tar is still here! */ /* Prepare for unblocking the data from the archive into the uncompressor. */ xdup2 (child_pipe[PWRITE], STDOUT_FILENO); xclose (child_pipe[PREAD]); if (strcmp (archive_name_array[0], "-") == 0) archive = STDIN_FILENO; else archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY, MODE_RW, rsh_command_option); if (archive < 0) open_fatal (archive_name_array[0]); /* Let's read the archive and pipe it into stdout. */ while (1) { char *cursor; size_t maximum; size_t count; size_t status; clear_read_error_count (); error_loop: status = rmtread (archive, record_start->buffer, record_size); if (status == SAFE_READ_ERROR) { archive_read_error (); goto error_loop; } if (status == 0) break; cursor = record_start->buffer; maximum = status; while (maximum) { count = maximum < BLOCKSIZE ? maximum : BLOCKSIZE; if (full_write (STDOUT_FILENO, cursor, count) != count) write_error (use_compress_program_option); cursor += count; maximum -= count; } } xclose (STDOUT_FILENO); wait_for_grandchild (grandchild_pid); }
/*@null@*/ char *ExecCommandWithArgs(char **args, int *myRet, /*@null@*/ const char *dataInput, int shouldReturnString) { size_t size = 0, ret; pid_t pid; char buffer[1024], *str = NULL; int fdsI[2], fdsO[2]; *myRet = -1; if (dataInput != NULL && pipe(fdsI) == -1) return (NULL); if (pipe(fdsO) == -1) { if (dataInput != NULL) { xclose(fdsI[0]); xclose(fdsI[1]); } return (NULL); } if ((pid = fork()) == 0) { if (dataInput != NULL) { xdup2(fdsI[0], 0); xclose(fdsI[0]); xclose(fdsI[1]); } xdup2(fdsO[1], 1); xdup2(fdsO[1], 2); xclose(fdsO[0]); xclose(fdsO[1]); (void) execv(args[0], args); exit(1); } else if (pid == -1) { if (dataInput != NULL) { xclose(fdsI[0]); xclose(fdsI[1]); } xclose(fdsO[0]); xclose(fdsO[1]); return (NULL); } if (dataInput != NULL) { size_t len, off, r; off = 0; len = strlen(dataInput); xclose(fdsI[0]); while ((r = write(fdsI[1], dataInput + off, len)) > 0) { off += r; len -= r; if (len == 0) break; } xclose(fdsI[1]); } xclose(fdsO[1]); str = malloc(1); if (str != NULL) { str[0] = '\0'; while ((ret = read(fdsO[0], buffer, sizeof(buffer))) > 0) { if (shouldReturnString == 1) { str = realloc(str, size + ret + 1); strncat(str, buffer, ret); } size += ret; } xclose(fdsO[0]); (void) waitpid(pid, myRet, 0); if (shouldReturnString == 1) return (str); free(str); } return (NULL); }
/* GetSYSPath() * ==================================================================== * Get the Paths for the EXTEND.SYS */ int GetSYSPath( char *sysfile, char *path ) { long len; /* Get the Bootup Device - It's either 'C' or 'A' */ Supexec( GetBootDrive ); drv = BootDrive; Drive = BootDrive + 'A'; path[0] = Drive; errno = 0; xopen( sysfile ); if( errno ) { /* Error - No SYS file */ return( errno ); } else { /* Found the SYS FILE */ lookahead = NO_TOKEN; /* Check for the PATH line at the top of the file. */ if( !match(PATH) ) { /* Error: No Path line at the top of the SYS file */ xclose(); return( 1 ); } skipequal(); /* Check for the PATH itself at the top of the file.*/ if( match(PATHSPEC) ) { /* Found the PATH */ strncpy( path, yytext, yyleng ); len = yyleng-1; if( path[len] != '\\' ) ++len; path[len] = '\0'; if( len > 2 ) /* below code fails for items like 'f:'*/ { if( !stat( path, &statbuf) ) errno = (isdir(&statbuf)) ? 0 : ENOTDIR; if( errno ) { /* Error Parsing the path */ xclose(); return( errno ); } } } else { /* Error parsing the PATH */ xclose(); return( 1 ); } } xclose(); return( 0 ); }
/* parse_extend() * ==================================================================== * Parse the EXTEND.SYS file to get the fonts... * ANother routine is used to parse and get the cache settings etc... * IN: int skip 0 - Don't skip anything, parse everything. * Used during a rez change or boot-up * 1 - Skip parsing the path. Used during a * directory change. */ int parse_extend( int skip ) { errno = 0; xopen( ExtendPath ); /* Check to see if the file 'EXTEND.SYS' exists. */ if( errno ) { /* NO- Its NOT HERE!!! */ /* There are NO Active Outline Fonts */ if( !skip ) { sprintf( Current.FontPath, "%c:", Drive ); /* set some defaults here ONLY when we are supposed * to parse EVERYTHING. This way when we are only * switching directories, the current values are * NOT affected. */ Current.SpeedoCacheSize = 100L; /* Set to 100K */ Current.BitMapCacheSize = 100L; Current.speedo_percent = 5; /* Set to 50% */ Current.point_size[0] = 10; } return( errno ); } if( !skip ) { strcpy( Current.FontPath, OutlinePath ); Current.SpeedoCacheSize = 0L; Current.BitMapCacheSize = 0L; Current.speedo_percent = 5; /* 50% */ Current.Width = 0; Current.point_size[0] = 10; strupr( &Current.FontPath[0] ); } lookahead = NO_TOKEN; skipequal(); match(PATH); skipequal(); match(PATHSPEC); advance(); while( !match(EOI) ) { if( match(BITCACHE) ) { skipequal(); if( match(NUMBER) ) { Current.BitMapCacheSize = atol( yytext )/1024L; advance(); } } else if( match(FSMCACHE) ) { skipequal(); if( match(NUMBER) ) { if( !skip ) Current.SpeedoCacheSize = atol( yytext )/1024L; advance(); } /* In case we have a 'comma'# * which is used to divide up the fsm_cache internally * BUT, if we don't have the comma#, don't mess us up. */ if( match( COMMA ) ) { advance(); if( match( NUMBER ) ) { if( !skip ) Current.speedo_percent = atoi( yytext ); advance(); } } } else if( match(WIDTH) ) { skipequal(); if( match(NUMBER) ) { if( !skip ) Current.Width = atoi( yytext ); advance(); } } else fonts(); } xclose(); return 0; }
bool AsyncReadFile::iter(QStringList *errors, QByteArray *acc_contents, bool *p_made_progress) { *p_made_progress = true; if(m_ofn.isEmpty()) { errors->append(QStringLiteral("iter() called but start() not called before")); return false; } // ******** ITER 1 if(m_fn.isEmpty()) { m_fn = m_ofn; c_filename = ::strdup(m_fn.toLocal8Bit().constData()); if(c_filename == NULL) { errors->append(QStringLiteral("out of memory")); return false; } return true; } // ******** ITER 2 if(!m_done_pipefork) { int fds_msg[2] = { -1, -1 }; int fds_content[2] = { -1, -1 }; if(!xpipe2(fds_msg, "error message", errors)) { return false; } if(m_getc) { if(!xpipe2(fds_content, "content", errors)) { return false; } } m_pid = ::fork(); if(m_pid < 0) { errors->append(make_latin1_errmsg(errno, "could not fork")); return false; } if(m_pid == 0) { char c_filename_short[20 + 1] = ""; { const size_t l = strlen(c_filename); const size_t start = (l > 20 ? l - 20 : 0); strncpy(c_filename_short, c_filename + start, 20); } if(::close(fds_msg[PIPE_READ])) { CLDMYDBG("close(error message FD=%d): %s", fds_msg[PIPE_READ], strerror(errno)); } else { CLDMYDBG("close(error message FD=%d)", fds_msg[PIPE_READ]); } fds_msg[PIPE_READ] = (-1); if(m_getc) { if(::close(fds_content[PIPE_READ])) { CLDMYDBG("close(content FD=%d): %s", fds_content[PIPE_READ], strerror(errno)); } else { CLDMYDBG("close(content FD=%d)", fds_content[PIPE_READ]); } fds_content[PIPE_READ] = (-1); } FILE *msgfd_h = ::fdopen(fds_msg[PIPE_WRITE], "w"); if(msgfd_h == NULL) { CLDMYDBG("could not fdopen(error message pipe FD=%d): %s", fds_msg[PIPE_WRITE], strerror(errno)); char msg[] = "could not convert pipe to FILE"; ssize_t byteswritten = ::write(fds_msg[PIPE_WRITE], msg, sizeof(msg)); (void) byteswritten; ::_exit(1); } // pipe write, file read child_read_file(c_filename, c_filename_short, msgfd_h, fds_content[PIPE_WRITE], m_maxreadsize, pipe_bufsize, fileread_bufsize, CLF_DEBUG_enabled); // should never return } ASFMYDBG("spawned kid PID=%d", m_pid); (void)xclose(fds_msg[PIPE_WRITE], "error message"); if(m_getc) { (void)xclose(fds_content[PIPE_WRITE], "content"); } m_msgfd = fds_msg[PIPE_READ]; m_contentfd = fds_content[PIPE_READ]; m_done_pipefork = true; return true; } // ******** ITER 3... if(!m_done) { bool got_errmsg_data = false; if(m_msgfd >= 0) { if(m_errmsg_buffer == NULL) { m_errmsg_buffer = (char *)::malloc(errmsg_bufsize); if(m_errmsg_buffer == NULL) { force_kill_child("no memory"); errors->append(make_latin1_errmsg(0, "no memory")); return false; } } if(!xread(m_msgfd, "error message", m_errmsg_buffer, errmsg_bufsize, errors, &m_acc_err, &got_errmsg_data)) { return false; } } bool got_content_data = false; if(m_contentfd >= 0 && m_getc) { if(m_content_buffer_pipe_from_child == NULL) { m_content_buffer_pipe_from_child = (char *)::malloc(pipe_bufsize); if(m_content_buffer_pipe_from_child == NULL) { force_kill_child("no memory"); errors->append(make_latin1_errmsg(0, "no memory")); return false; } } if(!xread(m_contentfd, "content", m_content_buffer_pipe_from_child, pipe_bufsize, errors, acc_contents, &got_content_data)) { return false; } } *p_made_progress = (got_errmsg_data || got_content_data); // we only do this if there is a chance it will be interesting if((m_msgfd < 0 && m_contentfd < 0) || (!*p_made_progress)) { bool got_pid_change = false; if(!xwaitpid(m_pid, errors, &got_pid_change)) { m_done = true; *p_made_progress = true; if(!m_acc_err.isEmpty()) { errors->append(err_xbin_2_local_qstring(m_acc_err)); m_acc_err.clear(); } return false; } *p_made_progress = (got_errmsg_data || got_content_data || got_pid_change); } return true; } // ******** ITER LAST if(m_done) { *p_made_progress = false; return false; } PROGRAMMERERROR("WTF"); }
static void backeval(struct blk_buf *bb, struct Strbuf *word, Char *cp, int literal) { ssize_t icnt; Char c, *ip; struct command faket; int hadnl; int pvec[2], quoted; Char *fakecom[2], ibuf[BUFSIZE]; char tibuf[BUFSIZE]; hadnl = 0; icnt = 0; quoted = (literal || (cp[0] & QUOTE)) ? QUOTE : 0; faket.t_dtyp = NODE_COMMAND; faket.t_dflg = F_BACKQ; faket.t_dlef = 0; faket.t_drit = 0; faket.t_dspr = 0; faket.t_dcom = fakecom; fakecom[0] = STRfakecom1; fakecom[1] = 0; /* * We do the psave job to temporarily change the current job so that the * following fork is considered a separate job. This is so that when * backquotes are used in a builtin function that calls glob the "current * job" is not corrupted. We only need one level of pushed jobs as long as * we are sure to fork here. */ psavejob(); cleanup_push(&faket, psavejob_cleanup); /* faket is only a marker */ /* * It would be nicer if we could integrate this redirection more with the * routines in sh.sem.c by doing a fake execute on a builtin function that * was piped out. */ mypipe(pvec); cleanup_push(&pvec[0], open_cleanup); cleanup_push(&pvec[1], open_cleanup); if (pfork(&faket, -1) == 0) { jmp_buf_t osetexit; struct command *t; size_t omark; xclose(pvec[0]); (void) dmove(pvec[1], 1); (void) dmove(SHDIAG, 2); initdesc(); closem(); arginp = cp; for (arginp = cp; *cp; cp++) { *cp &= TRIM; if (is_set(STRcsubstnonl) && (*cp == '\n' || *cp == '\r')) *cp = ' '; } /* * In the child ``forget'' everything about current aliases or * eval vectors. */ alvec = NULL; evalvec = NULL; alvecp = NULL; evalp = NULL; omark = cleanup_push_mark(); getexit(osetexit); for (;;) { (void) setexit(); justpr = 0; if (haderr) { /* unwind */ doneinp = 0; cleanup_pop_mark(omark); resexit(osetexit); reset(); } if (seterr) { xfree(seterr); seterr = NULL; } (void) lex(¶ml); cleanup_push(¶ml, lex_cleanup); if (seterr) stderror(ERR_OLD); alias(¶ml); t = syntax(paraml.next, ¶ml, 0); if (t == NULL) return; cleanup_push(t, syntax_cleanup); /* The F_BACKQ flag must set so the job output is correct if * printexitvalue is set. If it's not set, the job output * will have "Exit N" appended where N is the exit status. */ t->t_dflg = F_BACKQ|F_NOFORK; if (seterr) stderror(ERR_OLD); #ifdef SIGTSTP signal(SIGTSTP, SIG_IGN); #endif #ifdef SIGTTIN signal(SIGTTIN, SIG_IGN); #endif #ifdef SIGTTOU signal(SIGTTOU, SIG_IGN); #endif execute(t, -1, NULL, NULL, TRUE); cleanup_until(¶ml); } } cleanup_until(&pvec[1]); c = 0; ip = NULL; do { ssize_t cnt = 0; char *tmp; tmp = tibuf; for (;;) { while (icnt == 0) { int i, eof; ip = ibuf; icnt = xread(pvec[0], tmp, tibuf + BUFSIZE - tmp); eof = 0; if (icnt <= 0) { if (tmp == tibuf) goto eof; icnt = 0; eof = 1; } icnt += tmp - tibuf; i = 0; tmp = tibuf; while (tmp < tibuf + icnt) { int len; len = normal_mbtowc(&ip[i], tmp, tibuf + icnt - tmp); if (len == -1) { reset_mbtowc(); if (!eof && (size_t)(tibuf + icnt - tmp) < MB_CUR_MAX) { break; /* Maybe a partial character */ } ip[i] = (unsigned char) *tmp | INVALID_BYTE; /* Error */ } if (len <= 0) len = 1; i++; tmp += len; } if (tmp != tibuf) memmove (tibuf, tmp, tibuf + icnt - tmp); tmp = tibuf + (tibuf + icnt - tmp); icnt = i; } if (hadnl) break; --icnt; c = (*ip++ & TRIM); if (c == 0) break; #if defined(WINNT_NATIVE) || defined(__CYGWIN__) if (c == '\r') c = ' '; #endif /* WINNT_NATIVE || __CYGWIN__ */ if (c == '\n') { /* * Continue around the loop one more time, so that we can eat * the last newline without terminating this word. */ hadnl = 1; continue; } if (!quoted && (c == ' ' || c == '\t')) break; cnt++; Strbuf_append1(word, c | quoted); } /* * Unless at end-of-file, we will form a new word here if there were * characters in the word, or in any case when we take text literally. * If we didn't make empty words here when literal was set then we * would lose blank lines. */ if (c != 0 && (cnt || literal)) pword(bb, word); hadnl = 0; } while (c > 0); eof: cleanup_until(&pvec[0]); pwait(); cleanup_until(&faket); /* psavejob_cleanup(); */ }
/* * Form a shell temporary file (in unit 0) from the words * of the shell input up to EOF or a line the same as "term". * Unit 0 should have been closed before this call. */ void heredoc(Char *term) { eChar c; Char *Dv[2]; struct Strbuf lbuf = Strbuf_INIT, mbuf = Strbuf_INIT; Char obuf[BUFSIZE + 1]; #define OBUF_END (obuf + sizeof(obuf) / sizeof (*obuf) - 1) Char *lbp, *obp, *mbp; Char **vp; int quoted; #ifdef HAVE_MKSTEMP char *tmp = short2str(shtemp); char *dot = strrchr(tmp, '.'); if (!dot) stderror(ERR_NAME | ERR_NOMATCH); strcpy(dot, TMP_TEMPLATE); xclose(0); if (mkstemp(tmp) == -1) stderror(ERR_SYSTEM, tmp, strerror(errno)); #else /* !HAVE_MKSTEMP */ char *tmp; # ifndef WINNT_NATIVE again: # endif /* WINNT_NATIVE */ tmp = short2str(shtemp); # if O_CREAT == 0 if (xcreat(tmp, 0600) < 0) stderror(ERR_SYSTEM, tmp, strerror(errno)); # endif xclose(0); if (xopen(tmp, O_RDWR|O_CREAT|O_EXCL|O_TEMPORARY|O_LARGEFILE, 0600) == -1) { int oerrno = errno; # ifndef WINNT_NATIVE if (errno == EEXIST) { if (unlink(tmp) == -1) { xfree(shtemp); mbp = randsuf(); shtemp = Strspl(STRtmpsh, mbp); xfree(mbp); } goto again; } # endif /* WINNT_NATIVE */ (void) unlink(tmp); errno = oerrno; stderror(ERR_SYSTEM, tmp, strerror(errno)); } #endif /* HAVE_MKSTEMP */ (void) unlink(tmp); /* 0 0 inode! */ Dv[0] = term; Dv[1] = NULL; gflag = 0; trim(Dv); rscan(Dv, Dtestq); quoted = gflag; obp = obuf; obuf[BUFSIZE] = 0; inheredoc = 1; cleanup_push(&inheredoc, inheredoc_cleanup); #ifdef WINNT_NATIVE __dup_stdin = 1; #endif /* WINNT_NATIVE */ cleanup_push(&lbuf, Strbuf_cleanup); cleanup_push(&mbuf, Strbuf_cleanup); for (;;) { Char **words; /* * Read up a line */ lbuf.len = 0; for (;;) { c = readc(1); /* 1 -> Want EOF returns */ if (c == CHAR_ERR || c == '\n') break; if ((c &= TRIM) != 0) Strbuf_append1(&lbuf, (Char) c); } Strbuf_terminate(&lbuf); /* Catch EOF in the middle of a line. */ if (c == CHAR_ERR && lbuf.len != 0) c = '\n'; /* * Check for EOF or compare to terminator -- before expansion */ if (c == CHAR_ERR || eq(lbuf.s, term)) break; /* * If term was quoted or -n just pass it on */ if (quoted || noexec) { Strbuf_append1(&lbuf, '\n'); Strbuf_terminate(&lbuf); for (lbp = lbuf.s; (c = *lbp++) != 0;) { *obp++ = (Char) c; if (obp == OBUF_END) { tmp = short2str(obuf); (void) xwrite(0, tmp, strlen (tmp)); obp = obuf; } } continue; } /* * Term wasn't quoted so variable and then command expand the input * line */ Dcp = lbuf.s; Dvp = Dv + 1; mbuf.len = 0; for (;;) { c = DgetC(DODOL); if (c == DEOF) break; if ((c &= TRIM) == 0) continue; /* \ quotes \ $ ` here */ if (c == '\\') { c = DgetC(0); if (!any("$\\`", c)) unDgetC(c | QUOTE), c = '\\'; else c |= QUOTE; } Strbuf_append1(&mbuf, (Char) c); } Strbuf_terminate(&mbuf); /* * If any ` in line do command substitution */ mbp = mbuf.s; if (Strchr(mbp, '`') != NULL) { /* * 1 arg to dobackp causes substitution to be literal. Words are * broken only at newlines so that all blanks and tabs are * preserved. Blank lines (null words) are not discarded. */ words = dobackp(mbp, 1); } else /* Setup trivial vector similar to return of dobackp */ Dv[0] = mbp, Dv[1] = NULL, words = Dv; /* * Resurrect the words from the command substitution each separated by * a newline. Note that the last newline of a command substitution * will have been discarded, but we put a newline after the last word * because this represents the newline after the last input line! */ for (vp= words; *vp; vp++) { for (mbp = *vp; *mbp; mbp++) { *obp++ = *mbp & TRIM; if (obp == OBUF_END) { tmp = short2str(obuf); (void) xwrite(0, tmp, strlen (tmp)); obp = obuf; } } *obp++ = '\n'; if (obp == OBUF_END) { tmp = short2str(obuf); (void) xwrite(0, tmp, strlen (tmp)); obp = obuf; } } if (words != Dv) blkfree(words); } *obp = 0; tmp = short2str(obuf); (void) xwrite(0, tmp, strlen (tmp)); (void) lseek(0, (off_t) 0, L_SET); cleanup_until(&inheredoc); }
/* Set ARCHIVE for writing, then compressing an archive. */ pid_t sys_child_open_for_compress (void) { int parent_pipe[2]; int child_pipe[2]; pid_t grandchild_pid; pid_t child_pid; xpipe (parent_pipe); child_pid = xfork (); if (child_pid > 0) { /* The parent tar is still here! Just clean up. */ archive = parent_pipe[PWRITE]; xclose (parent_pipe[PREAD]); return child_pid; } /* The new born child tar is here! */ set_program_name (_("tar (child)")); signal (SIGPIPE, SIG_DFL); xdup2 (parent_pipe[PREAD], STDIN_FILENO); xclose (parent_pipe[PWRITE]); /* Check if we need a grandchild tar. This happens only if either: a) the file is to be accessed by rmt: compressor doesn't know how; b) the file is not a plain file. */ if (!_remdev (archive_name_array[0]) && is_regular_file (archive_name_array[0])) { if (backup_option) maybe_backup_file (archive_name_array[0], 1); /* We don't need a grandchild tar. Open the archive and launch the compressor. */ if (strcmp (archive_name_array[0], "-")) { archive = creat (archive_name_array[0], MODE_RW); if (archive < 0) { int saved_errno = errno; if (backup_option) undo_last_backup (); errno = saved_errno; open_fatal (archive_name_array[0]); } xdup2 (archive, STDOUT_FILENO); } execlp (use_compress_program_option, use_compress_program_option, NULL); exec_fatal (use_compress_program_option); } /* We do need a grandchild tar. */ xpipe (child_pipe); grandchild_pid = xfork (); if (grandchild_pid == 0) { /* The newborn grandchild tar is here! Launch the compressor. */ set_program_name (_("tar (grandchild)")); xdup2 (child_pipe[PWRITE], STDOUT_FILENO); xclose (child_pipe[PREAD]); execlp (use_compress_program_option, use_compress_program_option, (char *) 0); exec_fatal (use_compress_program_option); } /* The child tar is still here! */ /* Prepare for reblocking the data from the compressor into the archive. */ xdup2 (child_pipe[PREAD], STDIN_FILENO); xclose (child_pipe[PWRITE]); if (strcmp (archive_name_array[0], "-") == 0) archive = STDOUT_FILENO; else { archive = rmtcreat (archive_name_array[0], MODE_RW, rsh_command_option); if (archive < 0) open_fatal (archive_name_array[0]); } /* Let's read out of the stdin pipe and write an archive. */ while (1) { size_t status = 0; char *cursor; size_t length; /* Assemble a record. */ for (length = 0, cursor = record_start->buffer; length < record_size; length += status, cursor += status) { size_t size = record_size - length; status = safe_read (STDIN_FILENO, cursor, size); if (status == SAFE_READ_ERROR) read_fatal (use_compress_program_option); if (status == 0) break; } /* Copy the record. */ if (status == 0) { /* We hit the end of the file. Write last record at full length, as the only role of the grandchild is doing proper reblocking. */ if (length > 0) { memset (record_start->buffer + length, 0, record_size - length); status = sys_write_archive_buffer (); if (status != record_size) archive_write_error (status); } /* There is nothing else to read, break out. */ break; } status = sys_write_archive_buffer (); if (status != record_size) archive_write_error (status); } wait_for_grandchild (grandchild_pid); }
int main(int argc, char* argv[]) { int i = 1; int r = 0; FILE *ifile = NULL; FILE *ofile = NULL; int opt_var_decompress = 0; int opt_var_test = 0; int opt_verbose = 0; int opt_block_compress = 0; int opt_block_decompress = 0; int opt_file_md5 = 0; const char *in_name = NULL; const char *out_name = NULL; const char *s; /* * Step 1: init */ progname = argv[0]; for (s = progname; *s; s++) if ((*s == '/' || *s == '\\') && s[1]) progname = s + 1; #if 0 printf("QLZ test\n"); #endif /* * Step 2: get options */ while (i < argc && argv[i][0] == '-') { if (strcmp(argv[i],"-d") == 0) opt_var_decompress = 1; else if (strcmp(argv[i],"-t") == 0) opt_var_test = 1; else if (strcmp(argv[i],"-v") == 0) opt_verbose = 9; else if (strcmp(argv[i],"-k") == 0) opt_block_compress = 1; else if (strcmp(argv[i],"-x") == 0) opt_block_decompress = 1; else if (strcmp(argv[i],"-h") == 0) opt_file_md5 = 1; else if (strcmp(argv[i],"--debug") == 0) opt_debug += 1; else if (strcmp(argv[i],"-Z") == 0) opt_writezero = 1; else usage(); i++; } if (opt_var_test && i >= argc) usage(); if (!opt_var_test && !opt_file_md5 && i + 2 != argc) usage(); /* * Step 3: process file */ if (!opt_var_test && !opt_file_md5) { in_name = argv[i++]; out_name = argv[i++]; ifile = xopen_fi(in_name); ofile = xopen_fo(out_name); if (opt_block_compress) { r = tst_comp(ifile, ofile, opt_verbose); } else if (opt_block_decompress) { r = tst_decomp(ifile, ofile, opt_verbose); } else if (opt_var_decompress) { r = var_decompress(ifile, ofile, opt_verbose); if (r == 0) printf("%s: decompressed %llu into %llu bytes\n", progname, total_in, total_out); } else { printf("%s: nothing to do\n", progname); } xclose(ifile); xclose(ofile); } else /* opt_var_test || opt_file_md5 */ { in_name = argv[i++]; ifile = xopen_fi(in_name); if (opt_file_md5) { md5_byte_t digest[16]; char hex_output[16*2 + 1]; tst_md5(ifile, digest); str_to_hexstr((char *)digest, hex_output); printf("%s %s\n", hex_output, in_name); } else /* opt_var_test */ { r = var_decompress(ifile, NULL, opt_verbose); if (r == 0) printf("%s: %s tested ok (%llu -> %llu bytes)\n", progname, in_name, total_in, total_out); } xclose(ifile); } ifile = NULL; ofile = NULL; return r; }
int sys_exec_info_script (const char **archive_name, int volume_number) { pid_t pid; char *argv[4]; char uintbuf[UINTMAX_STRSIZE_BOUND]; int p[2]; static RETSIGTYPE (*saved_handler) (int sig); xpipe (p); saved_handler = signal (SIGPIPE, SIG_IGN); pid = xfork (); if (pid != 0) { /* Master */ int rc; int status; char *buf = NULL; size_t size = 0; FILE *fp; xclose (p[PWRITE]); fp = fdopen (p[PREAD], "r"); rc = getline (&buf, &size, fp); fclose (fp); if (rc > 0 && buf[rc-1] == '\n') buf[--rc] = 0; while (waitpid (pid, &status, 0) == -1) if (errno != EINTR) { signal (SIGPIPE, saved_handler); waitpid_error (info_script_option); return -1; } signal (SIGPIPE, saved_handler); if (WIFEXITED (status)) { if (WEXITSTATUS (status) == 0 && rc > 0) *archive_name = buf; else free (buf); return WEXITSTATUS (status); } free (buf); return -1; } /* Child */ setenv ("TAR_VERSION", PACKAGE_VERSION, 1); setenv ("TAR_ARCHIVE", *archive_name, 1); setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1); setenv ("TAR_BLOCKING_FACTOR", STRINGIFY_BIGINT (blocking_factor, uintbuf), 1); setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1); setenv ("TAR_FORMAT", archive_format_string (current_format == DEFAULT_FORMAT ? archive_format : current_format), 1); setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1); xclose (p[PREAD]); argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = (char*) info_script_option; argv[3] = NULL; execv (argv[0], argv); exec_fatal (info_script_option); }
static int decompress_file(struct deflate_decompressor *decompressor, const tchar *path, const struct options *options) { tchar *newpath = NULL; struct file_stream in; struct file_stream out; struct stat stbuf; int ret; int ret2; if (path != NULL && !options->to_stdout) { const tchar *suffix = get_suffix(path, options->suffix); if (suffix == NULL) { msg("\"%"TS"\" does not end with the .%"TS" suffix -- " "skipping", path, options->suffix); ret = -2; goto out; } newpath = xmalloc((suffix - path + 1) * sizeof(tchar)); tmemcpy(newpath, path, suffix - path); newpath[suffix - path] = '\0'; } ret = xopen_for_read(path, &in); if (ret != 0) goto out_free_newpath; if (!options->force && isatty(in.fd)) { msg("Refusing to read compressed data from terminal. " "Use -f to override.\nFor help, use -h."); ret = -1; goto out_close_in; } ret = stat_file(&in, &stbuf, options->force || newpath == NULL); if (ret != 0) goto out_close_in; ret = xopen_for_write(newpath, options->force, &out); if (ret != 0) goto out_close_in; ret = map_file_contents(&in, stbuf.st_size); if (ret != 0) goto out_close_out; ret = do_decompress(decompressor, &in, &out); if (ret != 0) goto out_close_out; if (path != NULL && newpath != NULL) restore_metadata(&out, newpath, &stbuf); ret = 0; out_close_out: ret2 = xclose(&out); if (ret == 0) ret = ret2; if (ret != 0 && newpath != NULL) tunlink(newpath); out_close_in: xclose(&in); if (ret == 0 && path != NULL && newpath != NULL && !options->keep) tunlink(path); out_free_newpath: free(newpath); out: return ret; }
void close_passive(struct s_static_socket *br) { if (br->pasv != -1) xclose(br->pasv); br->pasv = -1; }
static int compress_file(struct deflate_compressor *compressor, const tchar *path, const struct options *options) { tchar *newpath = NULL; struct file_stream in; struct file_stream out; struct stat stbuf; int ret; int ret2; if (path != NULL && !options->to_stdout) { size_t path_nchars, suffix_nchars; if (!options->force && has_suffix(path, options->suffix)) { msg("%"TS": already has .%"TS" suffix -- skipping", path, options->suffix); ret = -2; goto out; } path_nchars = tstrlen(path); suffix_nchars = tstrlen(options->suffix); newpath = xmalloc((path_nchars + 1 + suffix_nchars + 1) * sizeof(tchar)); tmemcpy(newpath, path, path_nchars); newpath[path_nchars] = '.'; tmemcpy(&newpath[path_nchars + 1], options->suffix, suffix_nchars + 1); } ret = xopen_for_read(path, &in); if (ret != 0) goto out_free_newpath; ret = stat_file(&in, &stbuf, options->force || newpath == NULL); if (ret != 0) goto out_close_in; ret = xopen_for_write(newpath, options->force, &out); if (ret != 0) goto out_close_in; if (!options->force && isatty(out.fd)) { msg("Refusing to write compressed data to terminal. " "Use -f to override.\nFor help, use -h."); ret = -1; goto out_close_out; } ret = map_file_contents(&in, stbuf.st_size); if (ret) goto out_close_out; ret = do_compress(compressor, &in, &out); if (ret != 0) goto out_close_out; if (path != NULL && newpath != NULL) restore_metadata(&out, newpath, &stbuf); ret = 0; out_close_out: ret2 = xclose(&out); if (ret == 0) ret = ret2; if (ret != 0 && newpath != NULL) tunlink(newpath); out_close_in: xclose(&in); if (ret == 0 && path != NULL && newpath != NULL && !options->keep) tunlink(path); out_free_newpath: free(newpath); out: return ret; }
int wget_main(int argc UNUSED_PARAM, char **argv) { char buf[512]; struct host_info server, target; len_and_sockaddr *lsa; unsigned opt; int redir_limit; char *proxy = NULL; char *dir_prefix = NULL; #if ENABLE_FEATURE_WGET_LONG_OPTIONS char *post_data; char *extra_headers = NULL; llist_t *headers_llist = NULL; #endif FILE *sfp; /* socket to web/ftp server */ FILE *dfp; /* socket to ftp server (data) */ char *fname_out; /* where to direct output (-O) */ int output_fd = -1; bool use_proxy; /* Use proxies if env vars are set */ const char *proxy_flag = "on"; /* Use proxies if env vars are set */ const char *user_agent = "Wget";/* "User-Agent" header field */ static const char keywords[] ALIGN1 = "content-length\0""transfer-encoding\0""chunked\0""location\0"; enum { KEY_content_length = 1, KEY_transfer_encoding, KEY_chunked, KEY_location }; #if ENABLE_FEATURE_WGET_LONG_OPTIONS static const char wget_longopts[] ALIGN1 = /* name, has_arg, val */ "continue\0" No_argument "c" "spider\0" No_argument "s" "quiet\0" No_argument "q" "output-document\0" Required_argument "O" "directory-prefix\0" Required_argument "P" "proxy\0" Required_argument "Y" "user-agent\0" Required_argument "U" /* Ignored: */ // "tries\0" Required_argument "t" // "timeout\0" Required_argument "T" /* Ignored (we always use PASV): */ "passive-ftp\0" No_argument "\xff" "header\0" Required_argument "\xfe" "post-data\0" Required_argument "\xfd" /* Ignored (we don't do ssl) */ "no-check-certificate\0" No_argument "\xfc" ; #endif INIT_G(); #if ENABLE_FEATURE_WGET_LONG_OPTIONS applet_long_options = wget_longopts; #endif /* server.allocated = target.allocated = NULL; */ opt_complementary = "-1" IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); opt = getopt32(argv, "csqO:P:Y:U:" /*ignored:*/ "t:T:", &fname_out, &dir_prefix, &proxy_flag, &user_agent, NULL, /* -t RETRIES */ NULL /* -T NETWORK_READ_TIMEOUT */ IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) IF_FEATURE_WGET_LONG_OPTIONS(, &post_data) ); #if ENABLE_FEATURE_WGET_LONG_OPTIONS if (headers_llist) { int size = 1; char *cp; llist_t *ll = headers_llist; while (ll) { size += strlen(ll->data) + 2; ll = ll->link; } extra_headers = cp = xmalloc(size); while (headers_llist) { cp += sprintf(cp, "%s\r\n", (char*)llist_pop(&headers_llist)); } } #endif /* TODO: compat issue: should handle "wget URL1 URL2..." */ target.user = NULL; parse_url(argv[optind], &target); /* Use the proxy if necessary */ use_proxy = (strcmp(proxy_flag, "off") != 0); if (use_proxy) { proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy"); if (proxy && proxy[0]) { server.user = NULL; parse_url(proxy, &server); } else { use_proxy = 0; } } if (!use_proxy) { server.port = target.port; if (ENABLE_FEATURE_IPV6) { server.host = xstrdup(target.host); } else { server.host = target.host; } } if (ENABLE_FEATURE_IPV6) strip_ipv6_scope_id(target.host); /* Guess an output filename, if there was no -O FILE */ if (!(opt & WGET_OPT_OUTNAME)) { fname_out = bb_get_last_path_component_nostrip(target.path); /* handle "wget http://kernel.org//" */ if (fname_out[0] == '/' || !fname_out[0]) fname_out = (char*)"index.html"; /* -P DIR is considered only if there was no -O FILE */ if (dir_prefix) fname_out = concat_path_file(dir_prefix, fname_out); } else { if (LONE_DASH(fname_out)) { /* -O - */ output_fd = 1; opt &= ~WGET_OPT_CONTINUE; } } #if ENABLE_FEATURE_WGET_STATUSBAR G.curfile = bb_get_last_path_component_nostrip(fname_out); #endif /* Impossible? if ((opt & WGET_OPT_CONTINUE) && !fname_out) bb_error_msg_and_die("can't specify continue (-c) without a filename (-O)"); */ /* Determine where to start transfer */ if (opt & WGET_OPT_CONTINUE) { output_fd = open(fname_out, O_WRONLY); if (output_fd >= 0) { G.beg_range = xlseek(output_fd, 0, SEEK_END); } /* File doesn't exist. We do not create file here yet. * We are not sure it exists on remove side */ } redir_limit = 5; resolve_lsa: lsa = xhost2sockaddr(server.host, server.port); if (!(opt & WGET_OPT_QUIET)) { char *s = xmalloc_sockaddr2dotted(&lsa->u.sa); fprintf(stderr, "Connecting to %s (%s)\n", server.host, s); free(s); } establish_session: if (use_proxy || !target.is_ftp) { /* * HTTP session */ char *str; int status; /* Open socket to http server */ sfp = open_socket(lsa); /* Send HTTP request */ if (use_proxy) { fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n", target.is_ftp ? "f" : "ht", target.host, target.path); } else { if (opt & WGET_OPT_POST_DATA) fprintf(sfp, "POST /%s HTTP/1.1\r\n", target.path); else fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path); } fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n", target.host, user_agent); #if ENABLE_FEATURE_WGET_AUTHENTICATION if (target.user) { fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6, base64enc_512(buf, target.user)); } if (use_proxy && server.user) { fprintf(sfp, "Proxy-Authorization: Basic %s\r\n", base64enc_512(buf, server.user)); } #endif if (G.beg_range) fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range); #if ENABLE_FEATURE_WGET_LONG_OPTIONS if (extra_headers) fputs(extra_headers, sfp); if (opt & WGET_OPT_POST_DATA) { char *estr = URL_escape(post_data); fprintf(sfp, "Content-Type: application/x-www-form-urlencoded\r\n"); fprintf(sfp, "Content-Length: %u\r\n" "\r\n" "%s", (int) strlen(estr), estr); /*fprintf(sfp, "Connection: Keep-Alive\r\n\r\n");*/ /*fprintf(sfp, "%s\r\n", estr);*/ free(estr); } else #endif { /* If "Connection:" is needed, document why */ fprintf(sfp, /* "Connection: close\r\n" */ "\r\n"); } /* * Retrieve HTTP response line and check for "200" status code. */ read_response: if (fgets(buf, sizeof(buf), sfp) == NULL) bb_error_msg_and_die("no response from server"); str = buf; str = skip_non_whitespace(str); str = skip_whitespace(str); // FIXME: no error check // xatou wouldn't work: "200 OK" status = atoi(str); switch (status) { case 0: case 100: while (gethdr(buf, sizeof(buf), sfp /*, &n*/) != NULL) /* eat all remaining headers */; goto read_response; case 200: /* Response 204 doesn't say "null file", it says "metadata has changed but data didn't": "10.2.5 204 No Content The server has fulfilled the request but does not need to return an entity-body, and might want to return updated metainformation. The response MAY include new or updated metainformation in the form of entity-headers, which if present SHOULD be associated with the requested variant. If the client is a user agent, it SHOULD NOT change its document view from that which caused the request to be sent. This response is primarily intended to allow input for actions to take place without causing a change to the user agent's active document view, although any new or updated metainformation SHOULD be applied to the document currently in the user agent's active view. The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields." However, in real world it was observed that some web servers (e.g. Boa/0.94.14rc21) simply use code 204 when file size is zero. */ case 204: break; case 300: /* redirection */ case 301: case 302: case 303: break; case 206: if (G.beg_range) break; /* fall through */ default: bb_error_msg_and_die("server returned error: %s", sanitize_string(buf)); } /* * Retrieve HTTP headers. */ while ((str = gethdr(buf, sizeof(buf), sfp /*, &n*/)) != NULL) { /* gethdr converted "FOO:" string to lowercase */ smalluint key; /* strip trailing whitespace */ char *s = strchrnul(str, '\0') - 1; while (s >= str && (*s == ' ' || *s == '\t')) { *s = '\0'; s--; } key = index_in_strings(keywords, buf) + 1; if (key == KEY_content_length) { G.content_len = BB_STRTOOFF(str, NULL, 10); if (G.content_len < 0 || errno) { bb_error_msg_and_die("content-length %s is garbage", sanitize_string(str)); } G.got_clen = 1; continue; } if (key == KEY_transfer_encoding) { if (index_in_strings(keywords, str_tolower(str)) + 1 != KEY_chunked) bb_error_msg_and_die("transfer encoding '%s' is not supported", sanitize_string(str)); G.chunked = G.got_clen = 1; } if (key == KEY_location && status >= 300) { if (--redir_limit == 0) bb_error_msg_and_die("too many redirections"); fclose(sfp); G.got_clen = 0; G.chunked = 0; if (str[0] == '/') /* free(target.allocated); */ target.path = /* target.allocated = */ xstrdup(str+1); /* lsa stays the same: it's on the same server */ else { parse_url(str, &target); if (!use_proxy) { server.host = target.host; /* strip_ipv6_scope_id(target.host); - no! */ /* we assume remote never gives us IPv6 addr with scope id */ server.port = target.port; free(lsa); goto resolve_lsa; } /* else: lsa stays the same: we use proxy */ } goto establish_session; } } // if (status >= 300) // bb_error_msg_and_die("bad redirection (no Location: header from server)"); /* For HTTP, data is pumped over the same connection */ dfp = sfp; } else { /* * FTP session */ sfp = prepare_ftp_session(&dfp, &target, lsa); } if (opt & WGET_OPT_SPIDER) { if (ENABLE_FEATURE_CLEAN_UP) fclose(sfp); return EXIT_SUCCESS; } if (output_fd < 0) { int o_flags = O_WRONLY | O_CREAT | O_TRUNC | O_EXCL; /* compat with wget: -O FILE can overwrite */ if (opt & WGET_OPT_OUTNAME) o_flags = O_WRONLY | O_CREAT | O_TRUNC; output_fd = xopen(fname_out, o_flags); } retrieve_file_data(dfp, output_fd); xclose(output_fd); if (dfp != sfp) { /* It's ftp. Close it properly */ fclose(dfp); if (ftpcmd(NULL, NULL, sfp, buf) != 226) bb_error_msg_and_die("ftp error: %s", sanitize_string(buf+4)); /* ftpcmd("QUIT", NULL, sfp, buf); - why bother? */ } return EXIT_SUCCESS; }
static int autocreate_sieve(const char *userid, const char *source_script) { /* XXX - this is really ugly, but too much work to tidy up right now -- Bron */ sieve_script_t *s = NULL; bytecode_info_t *bc = NULL; char *err = NULL; FILE *in_stream, *out_fp; int out_fd, in_fd, r, k; int do_compile = 0; const char *compiled_source_script = NULL; const char *sievename = get_script_name(source_script); const char *sieve_script_dir = NULL; char sieve_script_name[MAX_FILENAME]; char sieve_bcscript_name[MAX_FILENAME]; char sieve_default[MAX_FILENAME]; char sieve_tmpname[MAX_FILENAME]; char sieve_bctmpname[MAX_FILENAME]; char sieve_bclink_name[MAX_FILENAME]; char buf[4096]; mode_t oldmask; struct stat statbuf; /* We don't support using the homedirectory, like timsieved */ if (config_getswitch(IMAPOPT_SIEVEUSEHOMEDIR)) { syslog(LOG_WARNING,"autocreate_sieve: autocreate_sieve does not work with sieveusehomedir option in imapd.conf"); return 1; } /* Check if sievedir is defined in imapd.conf */ if(!config_getstring(IMAPOPT_SIEVEDIR)) { syslog(LOG_WARNING, "autocreate_sieve: sievedir option is not defined. Check imapd.conf"); return 1; } /* Check if autocreate_sieve_compiledscript is defined in imapd.conf */ if(!(compiled_source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT_COMPILED))) { syslog(LOG_WARNING, "autocreate_sieve: autocreate_sieve_compiledscript option is not defined. Compiling it"); do_compile = 1; } if (!(sieve_script_dir = user_sieve_path(userid))) { syslog(LOG_WARNING, "autocreate_sieve: unable to determine sieve directory for user %s", userid); return 1; } if(snprintf(sieve_tmpname, MAX_FILENAME, "%s/%s.script.NEW",sieve_script_dir, sievename) >= MAX_FILENAME) { syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid); return 1; } if(snprintf(sieve_bctmpname, MAX_FILENAME, "%s/%s.bc.NEW",sieve_script_dir, sievename) >= MAX_FILENAME) { syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid); return 1; } if(snprintf(sieve_script_name, MAX_FILENAME, "%s/%s.script",sieve_script_dir, sievename) >= MAX_FILENAME) { syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid); return 1; } if(snprintf(sieve_bcscript_name, MAX_FILENAME, "%s/%s.bc",sieve_script_dir, sievename) >= MAX_FILENAME) { syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid); return 1; } if(snprintf(sieve_default, MAX_FILENAME, "%s/%s",sieve_script_dir,"defaultbc") >= MAX_FILENAME) { syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid); return 1; } /* XXX no directory? umm */ if(snprintf(sieve_bclink_name, MAX_FILENAME, "%s.bc", sievename) >= MAX_FILENAME) { syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid); return 1; } /* Check if a default sieve filter alrady exists */ if(!stat(sieve_default,&statbuf)) { syslog(LOG_WARNING,"autocreate_sieve: Default sieve script already exists"); return 1; } /* Open the source script. if there is a problem with that exit */ in_stream = fopen(source_script, "r"); if(!in_stream) { syslog(LOG_WARNING,"autocreate_sieve: Unable to open sieve script %s. Check permissions",source_script); return 1; } /* * At this point we start the modifications of the filesystem */ /* Create the directory where the sieve scripts will reside */ r = cyrus_mkdir(sieve_bctmpname, 0755); if(r == -1) { /* If this fails we just leave */ fclose(in_stream); return 1; } /* * We open the file that will be used as the bc file. If this file exists, overwrite it * since something bad has happened. We open the file here so that this error checking is * done before we try to open the rest of the files to start copying etc. */ out_fd = open(sieve_bctmpname, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if(out_fd < 0) { if(errno == EEXIST) { syslog(LOG_WARNING,"autocreate_sieve: File %s already exists. Probaly left over. Ignoring",sieve_bctmpname); } else if (errno == EACCES) { syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_bctmpname); fclose(in_stream); return 1; } else { syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s: %m",sieve_bctmpname); fclose(in_stream); return 1; } } if(!do_compile && compiled_source_script && (in_fd = open(compiled_source_script, O_RDONLY)) != -1) { while((r = read(in_fd, buf, sizeof(buf))) > 0) { if((k=write(out_fd, buf,r)) < 0) { syslog(LOG_WARNING, "autocreate_sieve: Error writing to file %s: %m", sieve_bctmpname); close(out_fd); close(in_fd); fclose(in_stream); unlink(sieve_bctmpname); return 1; } } if(r == 0) { /* EOF */ xclose(out_fd); xclose(in_fd); } else if (r < 0) { syslog(LOG_WARNING, "autocreate_sieve: Error reading compiled script file %s: %m. Will try to compile it", compiled_source_script); xclose(in_fd); do_compile = 1; if(lseek(out_fd, 0, SEEK_SET)) { syslog(LOG_WARNING, "autocreate_sieve: Major IO problem (lseek: %m). Aborting"); xclose(out_fd); return 1; } } xclose(in_fd); } else { if(compiled_source_script) syslog(LOG_WARNING,"autocreate_sieve: Problem opening compiled script file: %s. Compiling it", compiled_source_script); do_compile = 1; } /* Because we failed to open a precompiled bc sieve script, we compile one */ if(do_compile) { if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) { if(err && *err) { syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script %s.",err); free(err); } else syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script"); unlink(sieve_bctmpname); fclose(in_stream); close(out_fd); return 1; } /* generate the bytecode */ if(sieve_generate_bytecode(&bc, s) == TIMSIEVE_FAIL) { syslog(LOG_WARNING,"autocreate_sieve: problem compiling sieve script"); /* removing the copied script and cleaning up memory */ unlink(sieve_bctmpname); sieve_script_free(&s); fclose(in_stream); close(out_fd); return 1; } if(sieve_emit_bytecode(out_fd, bc) == TIMSIEVE_FAIL) { syslog(LOG_WARNING,"autocreate_sieve: problem emiting sieve script"); /* removing the copied script and cleaning up memory */ unlink(sieve_bctmpname); sieve_free_bytecode(&bc); sieve_script_free(&s); fclose(in_stream); close(out_fd); return 1; } /* clean up the memory */ sieve_free_bytecode(&bc); sieve_script_free(&s); } xclose(out_fd); rewind(in_stream); /* Copy the initial script */ oldmask = umask(077); if((out_fp = fopen(sieve_tmpname, "w")) == NULL) { syslog(LOG_WARNING,"autocreate_sieve: Unable to open destination sieve script %s: %m", sieve_tmpname); unlink(sieve_bctmpname); umask(oldmask); fclose(in_stream); return 1; } umask(oldmask); while((r = fread(buf,sizeof(char), sizeof(buf), in_stream)) > 0) { if( fwrite(buf,sizeof(char), r, out_fp) != (unsigned)r) { syslog(LOG_WARNING,"autocreate_sieve: Problem writing to sieve script file %s: %m",sieve_tmpname); fclose(out_fp); unlink(sieve_tmpname); unlink(sieve_bctmpname); fclose(in_stream); return 1; } } if(feof(in_stream)) { fclose(out_fp); fclose(in_stream); } else { /* ferror */ fclose(out_fp); unlink(sieve_tmpname); unlink(sieve_bctmpname); fclose(in_stream); return 1; } /* Renaming the necessary stuff */ if(rename(sieve_tmpname, sieve_script_name)) { unlink(sieve_tmpname); unlink(sieve_bctmpname); return 1; } if(rename(sieve_bctmpname, sieve_bcscript_name)) { unlink(sieve_bctmpname); unlink(sieve_bcscript_name); return 1; } /* end now with the symlink */ if(symlink(sieve_bclink_name, sieve_default)) { if(errno != EEXIST) { syslog(LOG_WARNING, "autocreate_sieve: problem making the default link (symlink: %m)."); /* Lets delete the files */ unlink(sieve_script_name); unlink(sieve_bcscript_name); } } /* * If everything has succeeded AND we have compiled the script AND we have requested * to generate the global script so that it is not compiled each time then we create it. */ if(do_compile && config_getswitch(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT_COMPILE)) { if(!compiled_source_script) { syslog(LOG_WARNING, "autocreate_sieve: To save a compiled sieve script, autocreate_sieve_compiledscript must have been defined in imapd.conf"); return 0; } if(snprintf(sieve_tmpname, MAX_FILENAME, "%s.NEW", compiled_source_script) >= MAX_FILENAME) return 0; /* * Copy everything from the newly created bc sieve sieve script. */ if((in_fd = open(sieve_bcscript_name, O_RDONLY))<0) { return 0; } if((out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) { if(errno == EEXIST) { /* Someone is already doing this so just bail out. */ syslog(LOG_WARNING, "autocreate_sieve: %s already exists. Some other instance processing it, or it is left over", sieve_tmpname); close(in_fd); return 0; } else if (errno == EACCES) { syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_tmpname); close(in_fd); return 0; } else { syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s: %m",sieve_tmpname); close(in_fd); return 0; } } while((r = read(in_fd, buf, sizeof(buf))) > 0) { if((k = write(out_fd,buf,r)) < 0) { syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s: %m", sieve_tmpname); close(out_fd); close(in_fd); unlink(sieve_tmpname); return 0; } } if(r == 0 ) { /*EOF */ xclose(out_fd); xclose(in_fd); } else if (r < 0) { syslog(LOG_WARNING, "autocreate_sieve: Error reading file: %s: %m", sieve_bcscript_name); xclose(out_fd); xclose(in_fd); unlink(sieve_tmpname); return 0; } /* Rename the temporary created sieve script to its final name. */ if(rename(sieve_tmpname, compiled_source_script)) { if(errno != EEXIST) { unlink(sieve_tmpname); unlink(compiled_source_script); } return 0; } syslog(LOG_NOTICE, "autocreate_sieve: Compiled sieve script was successfully saved in %s", compiled_source_script); } return 0; }
/** * Waits for a FIFO to open on "the other side" * Takes the pathname of the fifo and the flag with which open should open the fifo * TODO review this */ void waitFifo(const char *pathname, int flags) { // opens the fifo and closes it right after xclose(xopen2(pathname, flags)); }
/* * Perform io redirection. * We may or maynot be forked here. */ static void doio(struct command *t, int *pipein, int *pipeout) { int fd; Char *cp; unsigned long flags = t->t_dflg; if (didfds || (flags & F_REPEAT)) return; if ((flags & F_READ) == 0) {/* F_READ already done */ if (t->t_dlef) { char *tmp; /* * so < /dev/std{in,out,err} work */ (void) dcopy(SHIN, 0); (void) dcopy(SHOUT, 1); (void) dcopy(SHDIAG, 2); cp = splicepipe(t, t->t_dlef); tmp = strsave(short2str(cp)); xfree(cp); cleanup_push(tmp, xfree); if ((fd = xopen(tmp, O_RDONLY|O_LARGEFILE)) < 0) stderror(ERR_SYSTEM, tmp, strerror(errno)); cleanup_until(tmp); /* allow input files larger than 2Gb */ #ifndef WINNT_NATIVE (void) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_LARGEFILE); #endif /*!WINNT_NATIVE*/ (void) dmove(fd, 0); } else if (flags & F_PIPEIN) { xclose(0); TCSH_IGNORE(dup(pipein[0])); xclose(pipein[0]); xclose(pipein[1]); } else if ((flags & F_NOINTERRUPT) && tpgrp == -1) { xclose(0); (void) xopen(_PATH_DEVNULL, O_RDONLY|O_LARGEFILE); } else { xclose(0); TCSH_IGNORE(dup(OLDSTD)); #if defined(CLOSE_ON_EXEC) && defined(CLEX_DUPS) /* * PWP: Unlike Bezerkeley 4.3, FIONCLEX for Pyramid is preserved * across dup()s, so we have to UNSET it here or else we get a * command with NO stdin, stdout, or stderr at all (a bad thing * indeed) */ (void) close_on_exec(0, 0); #endif /* CLOSE_ON_EXEC && CLEX_DUPS */ } } if (t->t_drit) { char *tmp; cp = splicepipe(t, t->t_drit); tmp = strsave(short2str(cp)); xfree(cp); cleanup_push(tmp, xfree); /* * so > /dev/std{out,err} work */ (void) dcopy(SHOUT, 1); (void) dcopy(SHDIAG, 2); if ((flags & F_APPEND) != 0) { #ifdef O_APPEND fd = xopen(tmp, O_WRONLY|O_APPEND|O_LARGEFILE); #else /* !O_APPEND */ fd = xopen(tmp, O_WRONLY|O_LARGEFILE); (void) lseek(fd, (off_t) 0, L_XTND); #endif /* O_APPEND */ } else fd = 0; if ((flags & F_APPEND) == 0 || fd == -1) { if (!(flags & F_OVERWRITE) && adrof(STRnoclobber)) { if (flags & F_APPEND) stderror(ERR_SYSTEM, tmp, strerror(errno)); chkclob(tmp); } if ((fd = xcreat(tmp, 0666)) < 0) stderror(ERR_SYSTEM, tmp, strerror(errno)); /* allow input files larger than 2Gb */ #ifndef WINNT_NATIVE (void) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_LARGEFILE); #endif /*!WINNT_NATIVE*/ } cleanup_until(tmp); (void) dmove(fd, 1); is1atty = isatty(1); } else if (flags & F_PIPEOUT) { xclose(1); TCSH_IGNORE(dup(pipeout[1])); is1atty = 0; } else { xclose(1); TCSH_IGNORE(dup(SHOUT)); is1atty = isoutatty; # if defined(CLOSE_ON_EXEC) && defined(CLEX_DUPS) (void) close_on_exec(1, 0); # endif /* CLOSE_ON_EXEC && CLEX_DUPS */ } xclose(2); if (flags & F_STDERR) { TCSH_IGNORE(dup(1)); is2atty = is1atty; } else { TCSH_IGNORE(dup(SHDIAG)); is2atty = isdiagatty; # if defined(CLOSE_ON_EXEC) && defined(CLEX_DUPS) (void) close_on_exec(2, 0); # endif /* CLOSE_ON_EXEC && CLEX_DUPS */ } didfds = 1; }
int file_main(char* ntfs_file, dis_context_t* dis_ctx) { // Check parameter if(!ntfs_file) { xprintf(L_ERROR, "Error, empty string file. Abort.\n"); return EXIT_FAILURE; } if(!dis_ctx) { xprintf(L_ERROR, "Error, no context given. Abort.\n"); return EXIT_FAILURE; } dis_iodata_t io_data = dis_ctx->io_data; size_t buf_size = (size_t)(NB_READ_SECTOR * io_data.sector_size); uint8_t* buffer = xmalloc(buf_size); mode_t mode = S_IRUSR|S_IWUSR; if(dis_ctx->cfg.is_ro & READ_ONLY) mode = S_IRUSR; int fd_ntfs = xopen2(ntfs_file, O_CREAT|O_RDWR|O_LARGEFILE, mode); off_t offset = 0; long long int percent = 0; xprintf(L_INFO, "File size: %llu bytes\n", io_data.volume_size); /* Read all sectors and decrypt them if necessary */ xprintf(L_INFO, "\rDecrypting... 0%%"); fflush(stdout); off_t decrypting_size = (off_t)io_data.volume_size; while(offset < decrypting_size) { /* Read and decrypt an entire region of the disk */ dislock(dis_ctx, buffer, offset, buf_size); offset += (off_t) buf_size; /* Now copy the required amount of data to the user file */ xwrite(fd_ntfs, buffer, buf_size); /* Screen update */ if(percent != (offset*100)/decrypting_size) { percent = (offset*100)/decrypting_size; xprintf(L_INFO, "\rDecrypting... %lld%%", percent); fflush(stdout); } } xprintf(L_INFO, "\rDecrypting... Done.\n"); xfree(buffer); xclose(fd_ntfs); return EXIT_SUCCESS; }
/*VARARGS 1*/ void execute(struct command *t, volatile int wanttty, int *pipein, int *pipeout, int do_glob) { int forked = 0; const struct biltins * volatile bifunc; pid_t pid = 0; int pv[2]; sigset_t set; static sigset_t csigset; #ifdef VFORK static int onosigchld = 0; #endif /* VFORK */ static int nosigchld = 0; (void) &wanttty; (void) &forked; (void) &bifunc; if (t == 0) return; #ifdef WINNT_NATIVE { if ((varval(STRNTslowexec) == STRNULL) && !t->t_dcdr && !t->t_dcar && !t->t_dflg && !didfds && (intty || intact) && (t->t_dtyp == NODE_COMMAND) && !isbfunc(t)) { if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE) (void) Strcpy(t->t_dcom[0], t->t_dcom[0] + 1); Dfix(t); if (nt_try_fast_exec(t) == 0) return; } } #endif /* WINNT_NATIVE */ /* * Ed [email protected] & Dominic [email protected] * Sat Feb 25 03:13:11 PST 1995 * try implicit cd if we have a 1 word command */ if (implicit_cd && (intty || intact) && t->t_dcom && t->t_dcom[0] && t->t_dcom[0][0] && (blklen(t->t_dcom) == 1) && !noexec) { Char *sCName; struct stat stbuf; char *pathname; sCName = dollar(t->t_dcom[0]); if (sCName != NULL && sCName[0] == '~') { struct Strbuf buf = Strbuf_INIT; const Char *name_end; for (name_end = sCName + 1; *name_end != '\0' && *name_end != '/'; name_end++) continue; if (name_end != sCName + 1) { Char *name, *home; name = Strnsave(sCName + 1, name_end - (sCName + 1)); home = gethdir(name); if (home != NULL) { Strbuf_append(&buf, home); xfree(home); } else Strbuf_append(&buf, name); xfree(name); } else Strbuf_append(&buf, varval(STRhome)); Strbuf_append(&buf, name_end); xfree(sCName); sCName = Strbuf_finish(&buf); } pathname = short2str(sCName); xfree(sCName); /* if this is a dir, tack a "cd" on as the first arg */ if (pathname != NULL && ((stat(pathname, &stbuf) != -1 && S_ISDIR(stbuf.st_mode)) #ifdef WINNT_NATIVE || (pathname[0] && pathname[1] == ':' && pathname[2] == '\0') #endif /* WINNT_NATIVE */ )) { Char *vCD[2]; Char **ot_dcom = t->t_dcom; vCD[0] = Strsave(STRcd); vCD[1] = NULL; t->t_dcom = blkspl(vCD, ot_dcom); xfree(ot_dcom); if (implicit_cd > 1) { blkpr(t->t_dcom); xputchar( '\n' ); } } } /* * From: Michael Schroeder <*****@*****.**> * Don't check for wantty > 0... */ if (t->t_dflg & F_AMPERSAND) wanttty = 0; switch (t->t_dtyp) { case NODE_COMMAND: if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE) memmove(t->t_dcom[0], t->t_dcom[0] + 1, (Strlen(t->t_dcom[0] + 1) + 1) * sizeof (*t->t_dcom[0])); if ((t->t_dflg & F_REPEAT) == 0) Dfix(t); /* $ " ' \ */ if (t->t_dcom[0] == 0) { return; } /*FALLTHROUGH*/ case NODE_PAREN: #ifdef BACKPIPE if (t->t_dflg & F_PIPEIN) mypipe(pipein); #else /* !BACKPIPE */ if (t->t_dflg & F_PIPEOUT) mypipe(pipeout); #endif /* BACKPIPE */ /* * Must do << early so parent will know where input pointer should be. * If noexec then this is all we do. */ if (t->t_dflg & F_READ) { xclose(0); heredoc(t->t_dlef); if (noexec) xclose(0); } setcopy(STRstatus, STR0, VAR_READWRITE); /* * This mess is the necessary kludge to handle the prefix builtins: * nice, nohup, time. These commands can also be used by themselves, * and this is not handled here. This will also work when loops are * parsed. */ while (t->t_dtyp == NODE_COMMAND) if (eq(t->t_dcom[0], STRnice)) { if (t->t_dcom[1]) { if (strchr("+-", t->t_dcom[1][0])) { if (t->t_dcom[2]) { setname("nice"); t->t_nice = (unsigned char)getn(t->t_dcom[1]); lshift(t->t_dcom, 2); t->t_dflg |= F_NICE; } else break; } else { t->t_nice = 4; lshift(t->t_dcom, 1); t->t_dflg |= F_NICE; } } else break; } else if (eq(t->t_dcom[0], STRnohup)) { if (t->t_dcom[1]) { t->t_dflg |= F_NOHUP; lshift(t->t_dcom, 1); } else break; } else if (eq(t->t_dcom[0], STRhup)) { if (t->t_dcom[1]) { t->t_dflg |= F_HUP; lshift(t->t_dcom, 1); } else break; } else if (eq(t->t_dcom[0], STRtime)) { if (t->t_dcom[1]) { t->t_dflg |= F_TIME; lshift(t->t_dcom, 1); } else break; } #ifdef F_VER else if (eq(t->t_dcom[0], STRver)) if (t->t_dcom[1] && t->t_dcom[2]) { setname("ver"); t->t_systype = getv(t->t_dcom[1]); lshift(t->t_dcom, 2); t->t_dflg |= F_VER; } else break; #endif /* F_VER */ else break; /* is it a command */ if (t->t_dtyp == NODE_COMMAND) { /* * Check if we have a builtin function and remember which one. */ bifunc = isbfunc(t); if (noexec) { /* * Continue for builtins that are part of the scripting language */ if (bifunc == NULL) break; if (bifunc->bfunct != (bfunc_t)dobreak && bifunc->bfunct != (bfunc_t)docontin && bifunc->bfunct != (bfunc_t)doelse && bifunc->bfunct != (bfunc_t)doend && bifunc->bfunct != (bfunc_t)doforeach&& bifunc->bfunct != (bfunc_t)dogoto && bifunc->bfunct != (bfunc_t)doif && bifunc->bfunct != (bfunc_t)dorepeat && bifunc->bfunct != (bfunc_t)doswbrk && bifunc->bfunct != (bfunc_t)doswitch && bifunc->bfunct != (bfunc_t)dowhile && bifunc->bfunct != (bfunc_t)dozip) break; } } else { /* not a command */ bifunc = NULL; if (noexec) break; } /* * GrP Executing a command - run jobcmd hook * Don't run for builtins * Don't run if we're not in a tty * Don't run if we're not really executing */ /* * CR - Charles Ross Aug 2005 * added "isoutatty". * The new behavior is that the jobcmd won't be executed * if stdout (SHOUT) isnt attached to a tty.. IE when * redirecting, or using backquotes etc.. */ if (t->t_dtyp == NODE_COMMAND && !bifunc && !noexec && intty && isoutatty) { Char *cmd = unparse(t); cleanup_push(cmd, xfree); job_cmd(cmd); cleanup_until(cmd); } /* * We fork only if we are timed, or are not the end of a parenthesized * list and not a simple builtin function. Simple meaning one that is * not pipedout, niced, nohupped, or &'d. It would be nice(?) to not * fork in some of these cases. */ #ifdef BACKPIPE /* * Can't have NOFORK for the tail of a pipe - because it is not the * last command spawned (even if it is at the end of a parenthesised * list). */ if (t->t_dflg & F_PIPEIN) t->t_dflg &= ~(F_NOFORK); #else /* * "command | builtin" may cause major misbehaviour as noted in * in the BUGS file entry * Subject: Redirected input to built-in functions misbehaves badly * forking when the builtin is the end of the pipe corrects the * problem. */ if (bifunc && (t->t_dflg & F_PIPEIN)) t->t_dflg &= ~(F_NOFORK); #endif /* BACKPIPE */ /* * Prevent forking cd, pushd, popd, chdir cause this will cause the * shell not to change dir! (XXX: but only for nice?) */ if (bifunc && (bifunc->bfunct == (bfunc_t)dochngd || bifunc->bfunct == (bfunc_t)dopushd || bifunc->bfunct == (bfunc_t)dopopd)) t->t_dflg &= ~(F_NICE); if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 && (!bifunc || t->t_dflg & (F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP | F_HUP)))) || /* * We have to fork for eval too. */ (bifunc && (t->t_dflg & F_PIPEIN) != 0 && bifunc->bfunct == (bfunc_t)doeval)) { #ifdef VFORK if (t->t_dtyp == NODE_PAREN || t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) #endif /* VFORK */ { forked++; /* * We need to block SIGCHLD here, so that if the process does * not die before we can set the process group */ if (wanttty >= 0 && !nosigchld) { sigemptyset(&set); sigaddset(&set, SIGCHLD); (void)sigprocmask(SIG_BLOCK, &set, &csigset); nosigchld = 1; } pid = pfork(t, wanttty); if (pid == 0 && nosigchld) { sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } else if (pid != 0 && (t->t_dflg & F_AMPERSAND)) backpid = pid; } #ifdef VFORK else { int ochild, osetintr, ohaderr, odidfds; int oSHIN, oSHOUT, oSHDIAG, oOLDSTD, otpgrp; int oisoutatty, oisdiagatty; sigset_t oset, ocsigset; # ifndef CLOSE_ON_EXEC int odidcch; # endif /* !CLOSE_ON_EXEC */ /* * Prepare for the vfork by saving everything that the child * corrupts before it exec's. Note that in some signal * implementations which keep the signal info in user space * (e.g. Sun's) it will also be necessary to save and restore * the current sigvec's for the signals the child touches * before it exec's. */ /* * Sooooo true... If this is a Sun, save the sigvec's. (Skip * Gilbrech - 11/22/87) */ # ifdef SAVESIGVEC struct sigaction savesv[NSIGSAVED]; sigset_t savesm; # endif /* SAVESIGVEC */ if (wanttty >= 0 && !nosigchld && !noexec) { sigemptyset(&set); sigaddset(&set, SIGCHLD); (void)sigprocmask(SIG_BLOCK, &set, &csigset); nosigchld = 1; } sigemptyset(&set); sigaddset(&set, SIGCHLD); sigaddset(&set, SIGINT); (void)sigprocmask(SIG_BLOCK, &set, &oset); ochild = child; osetintr = setintr; ohaderr = haderr; odidfds = didfds; # ifndef CLOSE_ON_EXEC odidcch = didcch; # endif /* !CLOSE_ON_EXEC */ oSHIN = SHIN; oSHOUT = SHOUT; oSHDIAG = SHDIAG; oOLDSTD = OLDSTD; otpgrp = tpgrp; oisoutatty = isoutatty; oisdiagatty = isdiagatty; ocsigset = csigset; onosigchld = nosigchld; Vsav = Vdp = 0; Vexpath = 0; Vt = 0; # ifdef SAVESIGVEC savesigvec(savesv, savesm); # endif /* SAVESIGVEC */ if (use_fork) pid = fork(); else pid = vfork(); if (pid < 0) { # ifdef SAVESIGVEC restoresigvec(savesv, savesm); # endif /* SAVESIGVEC */ sigprocmask(SIG_SETMASK, &oset, NULL); stderror(ERR_NOPROC); } forked++; if (pid) { /* parent */ # ifdef SAVESIGVEC restoresigvec(savesv, savesm); # endif /* SAVESIGVEC */ child = ochild; setintr = osetintr; haderr = ohaderr; didfds = odidfds; SHIN = oSHIN; # ifndef CLOSE_ON_EXEC didcch = odidcch; # endif /* !CLOSE_ON_EXEC */ SHOUT = oSHOUT; SHDIAG = oSHDIAG; OLDSTD = oOLDSTD; tpgrp = otpgrp; isoutatty = oisoutatty; isdiagatty = oisdiagatty; csigset = ocsigset; nosigchld = onosigchld; xfree(Vsav); Vsav = 0; xfree(Vdp); Vdp = 0; xfree(Vexpath); Vexpath = 0; blk_cleanup(Vt); Vt = 0; /* this is from pfork() */ palloc(pid, t); sigprocmask(SIG_SETMASK, &oset, NULL); } else { /* child */ /* this is from pfork() */ pid_t pgrp; int ignint = 0; if (nosigchld) { sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } if (setintr) ignint = (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) || (gointr && eq(gointr, STRminus)); pgrp = pcurrjob ? pcurrjob->p_jobid : getpid(); child++; if (setintr) { setintr = 0; /* * casts made right for SunOS 4.0 by Douglas C. Schmidt * <*****@*****.**> * (thanks! -- PWP) * * ignint ifs cleaned by Johan Widen <[email protected]> * (thanks again) */ if (ignint) { (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); } else { (void) signal(SIGINT, vffree); (void) signal(SIGQUIT, SIG_DFL); } # ifdef BSDJOBS if (wanttty >= 0) { (void) signal(SIGTSTP, SIG_DFL); (void) signal(SIGTTIN, SIG_DFL); (void) signal(SIGTTOU, SIG_DFL); } # endif /* BSDJOBS */ sigaction(SIGTERM, &parterm, NULL); } else if (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) { (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); } pgetty(wanttty, pgrp); if (t->t_dflg & F_NOHUP) (void) signal(SIGHUP, SIG_IGN); if (t->t_dflg & F_HUP) (void) signal(SIGHUP, SIG_DFL); if (t->t_dflg & F_NICE) { int nval = SIGN_EXTEND_CHAR(t->t_nice); # if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS) if (setpriority(PRIO_PROCESS, 0, nval) == -1 && errno) stderror(ERR_SYSTEM, "setpriority", strerror(errno)); # else /* !HAVE_SETPRIORITY || !PRIO_PROCESS */ (void) nice(nval); # endif /* HAVE_SETPRIORITY && PRIO_PROCESS */ } # ifdef F_VER if (t->t_dflg & F_VER) { tsetenv(STRSYSTYPE, t->t_systype ? STRbsd43 : STRsys53); dohash(NULL, NULL); } # endif /* F_VER */ } } #endif /* VFORK */ } if (pid != 0) { /* * It would be better if we could wait for the whole job when we * knew the last process had been started. Pwait, in fact, does * wait for the whole job anyway, but this test doesn't really * express our intentions. */ #ifdef BACKPIPE if (didfds == 0 && t->t_dflg & F_PIPEOUT) { xclose(pipeout[0]); xclose(pipeout[1]); } if ((t->t_dflg & F_PIPEIN) != 0) break; #else /* !BACKPIPE */ if (didfds == 0 && t->t_dflg & F_PIPEIN) { xclose(pipein[0]); xclose(pipein[1]); } if ((t->t_dflg & F_PIPEOUT) != 0) break; #endif /* BACKPIPE */ if (nosigchld) { sigprocmask(SIG_SETMASK, &csigset, NULL); nosigchld = 0; } if ((t->t_dflg & F_AMPERSAND) == 0) pwait(); break; } doio(t, pipein, pipeout); #ifdef BACKPIPE if (t->t_dflg & F_PIPEIN) { xclose(pipein[0]); xclose(pipein[1]); } #else /* !BACKPIPE */ if (t->t_dflg & F_PIPEOUT) { xclose(pipeout[0]); xclose(pipeout[1]); } #endif /* BACKPIPE */ /* * Perform a builtin function. If we are not forked, arrange for * possible stopping */ if (bifunc) { if (forked) { func(t, bifunc); exitstat(); } else { jmp_buf_t oldexit; int ohaderr = haderr; getexit(oldexit); if (setexit() == 0) func(t, bifunc); resexit(oldexit); haderr = ohaderr; if (adrof(STRprintexitvalue)) { int rv = getn(varval(STRstatus)); if (rv != 0) xprintf(CGETS(17, 2, "Exit %d\n"), rv); } } break; } if (t->t_dtyp != NODE_PAREN) { doexec(t, do_glob); /* NOTREACHED */ } /* * For () commands must put new 0,1,2 in FSH* and recurse */ if ((OLDSTD = dcopy(0, FOLDSTD)) >= 0) (void)close_on_exec(OLDSTD, 1); if ((SHOUT = dcopy(1, FSHOUT)) >= 0) { (void)close_on_exec(SHOUT, 1); isoutatty = isatty(SHOUT); } if ((SHDIAG = dcopy(2, FSHDIAG)) >= 0) { (void)close_on_exec(SHDIAG, 1); isdiagatty = isatty(SHDIAG); } xclose(SHIN); SHIN = -1; #ifndef CLOSE_ON_EXEC didcch = 0; #else (void) close_on_exec(FSHOUT, 1); (void) close_on_exec(FSHDIAG, 1); (void) close_on_exec(FOLDSTD, 1); #endif /* !CLOSE_ON_EXEC */ didfds = 0; wanttty = -1; t->t_dspr->t_dflg |= t->t_dflg & (F_NOINTERRUPT | F_BACKQ); execute(t->t_dspr, wanttty, NULL, NULL, do_glob); exitstat(); case NODE_PIPE: #ifdef BACKPIPE t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg & (F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT | F_BACKQ)); execute(t->t_dcdr, wanttty, pv, pipeout, do_glob); t->t_dcar->t_dflg |= F_PIPEOUT | (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT | F_BACKQ)); execute(t->t_dcar, wanttty, pipein, pv, do_glob); #else /* !BACKPIPE */ t->t_dcar->t_dflg |= F_PIPEOUT | (t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT | F_BACKQ)); execute(t->t_dcar, wanttty, pipein, pv, do_glob); t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg & (F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT | F_BACKQ)); execute(t->t_dcdr, wanttty, pv, pipeout, do_glob); #endif /* BACKPIPE */ break; case NODE_LIST: if (t->t_dcar) { t->t_dcar->t_dflg |= t->t_dflg & (F_NOINTERRUPT | F_BACKQ); execute(t->t_dcar, wanttty, NULL, NULL, do_glob); /* * In strange case of A&B make a new job after A */ if (t->t_dcar->t_dflg & F_AMPERSAND && t->t_dcdr && (t->t_dcdr->t_dflg & F_AMPERSAND) == 0) pendjob(); } if (t->t_dcdr) { t->t_dcdr->t_dflg |= t->t_dflg & (F_NOFORK | F_NOINTERRUPT | F_BACKQ); execute(t->t_dcdr, wanttty, NULL, NULL, do_glob); } break; case NODE_OR: case NODE_AND: if (t->t_dcar) { t->t_dcar->t_dflg |= t->t_dflg & (F_NOINTERRUPT | F_BACKQ); execute(t->t_dcar, wanttty, NULL, NULL, do_glob); if ((getn(varval(STRstatus)) == 0) != (t->t_dtyp == NODE_AND)) { return; } } if (t->t_dcdr) { t->t_dcdr->t_dflg |= t->t_dflg & (F_NOFORK | F_NOINTERRUPT | F_BACKQ); execute(t->t_dcdr, wanttty, NULL, NULL, do_glob); } break; default: break; } /* * Fall through for all breaks from switch * * If there will be no more executions of this command, flush all file * descriptors. Places that turn on the F_REPEAT bit are responsible for * doing donefds after the last re-execution */ if (didfds && !(t->t_dflg & F_REPEAT)) donefds(); }