/* returns: 0 in case of succes 1 in ... (still not in use) 2 in syntax error -1 in unexpected error */ int parse_cmd_line (cmd_line_t *cmd_line, const char *cmd) { size_t prv_cmd_beg = 0, i, cmd_len; /*used to get return of functions*/ int raux; /*STDIN, STDOUT, STDERR*/ int io_redir_seen=-1; /*return status*/ int ret = 0; sysfail (cmd_line==NULL, -1); cmd_len = strlen (cmd); /*assuming that the last thing is io redirection or nonblocking indicator*/ for (i=0; i < cmd_len && !IS_IO_REDIR (cmd[i]) && !IS_NONBLOCK (cmd[i]); ++i) { if (IS_PIPE (cmd[i])) { raux = pipe_list_push_cmd (cmd_line, cmd + prv_cmd_beg, i-prv_cmd_beg); sysfail (raux<0, -1); prv_cmd_beg = i + 1; } } /*last command (the one that comes after the last pipe)*/ if (prv_cmd_beg < cmd_len) { raux = pipe_list_push_cmd (cmd_line, cmd + prv_cmd_beg, i-prv_cmd_beg); sysfail (raux<0, -1); if (IS_EMPTY_LINE (raux)) { if (cmd_line->pipe_list_head != NULL) ret |= SYNTAX_ERROR; else ret |= EMPTY_LINE; return ret; } prv_cmd_beg = i + 1; } for (;i < cmd_len && !IS_NONBLOCK(cmd[i]); ++i) { /*todo: recognize output redir*/ if (IS_IO_REDIR (cmd[i])) { if (io_redir_seen != -1) cmd_line->io[io_redir_seen] = stringndup (cmd + prv_cmd_beg, i-prv_cmd_beg); prv_cmd_beg = i + 1; io_redir_seen = (IS_INPUT_REDIR (cmd[i])) ? 0 : 1; } else if (IS_PIPE (cmd[i])) ret |= SYNTAX_ERROR; } if (prv_cmd_beg < cmd_len && io_redir_seen != -1) cmd_line->io[io_redir_seen] = stringndup (cmd + prv_cmd_beg, i-prv_cmd_beg); /*if it is non_block it must be the last thing*/ cmd_line->is_nonblock = i < cmd_len && IS_NONBLOCK (cmd[i]); if (i < cmd_len-1) ret |= SYNTAX_ERROR; return ret; }
/*int set_job_foreground(list_node_t *n) { int aux, status; aux = tcsetpgrp(0, n->value->pgid); sysfail (aux < 0, -1); aux = kill(-n->value->pgid, SIGCONT); sysfail (aux < 0, -1); while(1) { aux = waitpid(-1, &status, WUNTRACED); if(set_job_status(aux, status) < 0) break; } sysfail (aux < 0, -1); aux = tcsetpgrp(0, getpgrp()); sysfail (aux < 0, -1); return 0; }*/ int set_job_foreground(list_node_t *n) { int aux = kill(-n->value->pid, SIGCONT); sysfail(aux < 0, -1); tcsetpgrp(STDIN_FILENO, n->value->pgid); aux = waitpid(n->value->pid, NULL, 0); sysfail(aux < 0, -1); tcsetpgrp(STDIN_FILENO, getpgid(0)); return aux; }
/* Alocate memory for a command_t. */ buffer_t *new_command_line (void) { buffer_t *command_line; command_line = malloc (sizeof(buffer_t)); sysfail (!command_line, NULL); command_line->size = BUFFER_STEP; command_line->buffer = malloc (BUFFER_STEP * sizeof(char)); if (command_line->buffer == NULL) { free (command_line); sysfail (1, NULL); } return command_line; }
sh_string *new_command_line (void) { sh_string *command_line; command_line = malloc (sizeof(sh_string)); sysfail (!command_line, NULL); command_line->size = STRING_SIZE; command_line->buffer = malloc (STRING_SIZE *sizeof(char)); if (command_line->buffer == NULL) { free (command_line); sysfail (1, NULL); } return command_line; }
static void read_stdin(void) { int anydone, r; char *newline, *space; anydone= 0; while (!anydone || used) { while (!(newline= memchr(buf,'\n',used))) { if (used == avail) { avail += 20; avail <<= 1; buf= realloc(buf,avail); if (!buf) sysfail("realloc stdin buffer",errno); } do { r= read(0,buf+used,avail-used); } while (r < 0 && errno == EINTR); if (r == 0) { if (used) { /* fake up final newline */ buf[used++]= '\n'; r= 1; } else { ov_pipe= 0; return; } } if (r < 0) sysfail("read stdin",errno); used += r; } *newline++= 0; space= strchr(buf,' '); if (space) *space++= 0; process_optarg(buf,0,space); used -= (newline-buf); memmove(buf,newline,used); anydone= 1; } }
void *xmalloc(size_t sz) { void *p; p= malloc(sz); if (!p) sysfail("malloc",sz); return p; }
/*cmd_str -> start of the command n -> number of bytes which is in the command */ struct qelem *new_qelem (const char *cmd_str, size_t n) { struct qelem *rqelem = malloc (sizeof (struct qelem)); sysfail (rqelem==NULL, NULL); rqelem->q_forw = NULL; rqelem->q_back = NULL; rqelem->q_data = (char *)stringndup (cmd_str, n); return rqelem; }
cmd_line_t* new_cmd_line (void) { cmd_line_t *cmd = malloc (sizeof (cmd_line_t)); sysfail (cmd==NULL, NULL); cmd->io[0] = cmd->io[1] = cmd->io[2] = NULL; cmd->pipe_list_head = NULL; cmd->pipe_list_tail = NULL; cmd->is_nonblock = 0; return cmd; }
int main(int argc, const char *const *argv) { struct timeval *tv, tvbuf; adns_query qu; void *qun_v; adns_answer *answer; int r, maxfd; fd_set readfds, writefds, exceptfds; const char *arg; ensure_adns_init(); while ((arg= *++argv)) process_optarg(arg,&argv,0); if (!ov_pipe && !ads) usageerr("no domains given, and -f/--pipe not used; try --help"); for (;;) { for (;;) { qu= ov_asynch ? 0 : outstanding.head ? outstanding.head->qu : 0; r= adns_check(ads,&qu,&answer,&qun_v); if ((r == EAGAIN) || (r == EWOULDBLOCK)) break; if (r == ESRCH) { if (!ov_pipe) goto x_quit; else break; } assert(!r); query_done(qun_v,answer); } maxfd= 0; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); if (ov_pipe) { maxfd= 1; FD_SET(0,&readfds); } tv= 0; adns_beforeselect(ads, &maxfd, &readfds,&writefds,&exceptfds, &tv,&tvbuf,0); ADNS_CLEAR_ERRNO; r= select(maxfd, &readfds,&writefds,&exceptfds, tv); ADNS_CAPTURE_ERRNO; if (r == -1) { if (errno == EINTR) continue; sysfail("select",errno); } adns_afterselect(ads, maxfd, &readfds,&writefds,&exceptfds, 0); if (ov_pipe && FD_ISSET(0,&readfds)) read_stdin(); } x_quit: if (fclose(stdout)) outerr(); quitnow(rcode); }
char *stringdup (const char *str) { char *p; int n; n = strlen (str) + 1; p = malloc (n * sizeof(char)); sysfail (!p, NULL); strcpy (p, str); return p; }
/* Read a line from standard input and store it in command_line->buffer. The buffer size is enlarged if needed in steps of size BUFFER_STEP. Return the number of bytes read or -1 on error. */ int read_command_line (buffer_t *command_line) { int read_bytes, count, temp; int read_more = 1; char *offset, *p; int howmany; count = 0; offset = command_line->buffer; howmany = command_line->size; while (read_more) { /* Read howmany bytes. */ read_bytes = read(1, offset, howmany); count += read_bytes; /* This happens also if the previous read left a trailing newline. */ if (offset[0] == '\n') { offset[0] = '\0'; command_line->length = 0; return --count; } read_more = 0; if (read_bytes < howmany) offset[read_bytes - 1] = '\0'; /* We read less than howmany; done. */ else if (offset[read_bytes - 1] == '\n') offset[read_bytes - 1] = '\0'; /* We read exactly howmany; done. */ else /* There is more to read. */ { /* Enlarge buffer. */ temp = command_line->size; p = realloc (command_line->buffer, (temp + BUFFER_STEP) * sizeof(char)); sysfail (!p, -1); /* Offest is the end of the buffer. */ offset = command_line->buffer + count; command_line->size += BUFFER_STEP; howmany = BUFFER_STEP; read_more = 1; } } command_line->length = count; return count; }
void open_video(void) { struct v4l2_format v; dev_fd = open(device, O_RDWR); if (dev_fd == -1) sysfail(device); v.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; vidioc(G_FMT, &v); v.fmt.pix.width = frame_width; v.fmt.pix.height = frame_height; v.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; v.fmt.pix.sizeimage = rgb_frame_bytes; vidioc(S_FMT, &v); }
/* returns -1 in case of error */ int pipe_list_push_cmd (cmd_line_t *cmd_line, const char *cmd_str, size_t n) { struct qelem *nelem = new_qelem (cmd_str, n); sysfail (nelem==NULL, -1); if (strlen (nelem->q_data) == 0) { free (nelem->q_data); free (nelem); return EMPTY_LINE; } insque (nelem, cmd_line->pipe_list_tail); cmd_line->pipe_list_tail = nelem; if (cmd_line->pipe_list_head == NULL) cmd_line->pipe_list_head = cmd_line->pipe_list_tail; return EXIT_SUCCESS; }
void copy_frames(void) { char *frame; frame = malloc(rgb_frame_bytes); if (frame == NULL) fail("cannot malloc frame"); //int correctFrame = 0; //int corruptFrame = 0; while (1) { int size_c = fread(frame, 1, rgb_frame_bytes, stdin); //printf("%d\n",size_c); //if(size_c == rgb_frame_bytes) //{ // correctFrame++; // printf("%d corrupt frame\n Correct Frame: %d\n",corruptFrame, correctFrame); // corruptFrame = 0; //} //else //if(size_c != 0) //{ // printf("%d correct frame\n size = %d\n",correctFrame,size_c); // correctFrame = 0; // corruptFrame++; //} if ( size_c != rgb_frame_bytes) { free(frame); fail("malformed frame"); } else { //TODO: convert yuv frame to rgb -> conversion done in BebopDroneDecodeStream, now reading RGB24 frames from fifo //if(size_c != 0) if (write(dev_fd, frame, rgb_frame_bytes) != rgb_frame_bytes) { free(frame); sysfail("write"); } } //usleep(300); } free(frame); }
/* copies the first n bytes of a string also puts a \0 at the end also trims the string */ char *stringndup(const char *str, size_t n) { char *rstr; int poff=0; /*offset, how many bytes are blank at the begining*/ /*triming*/ while (str[poff] != '\0' && (iscntrl (str[poff]) || isblank (str[poff]))) poff++; n -= poff; while (n>0 && (iscntrl (str[poff + n-1]) || isblank (str[poff + n - 1]))) --n; /*end triming*/ rstr = malloc (sizeof (char) * (n+1)); sysfail (rstr==NULL, NULL); rstr[n] = '\0'; strncpy (rstr, str + poff, n); return rstr; }
/* Allocate memory for a new pipeline. */ pipeline_t *new_pipeline (void) { pipeline_t *pipeline; int i, j; pipeline = malloc (1 * sizeof(pipeline_t)); sysfail (!pipeline, NULL); /* Allocate a pipeline structure. */ pipeline->command = malloc ((MAX_COMMANDS + 1) * sizeof(char **)); if (!pipeline->command) { sysdebug (1); free (pipeline); return NULL; } /* Allocate memory for commands. */ for (i = 0; i < MAX_COMMANDS + 1; i++) { pipeline->command[i] = malloc ((MAX_ARGUMENTS + 1) * sizeof (char *)); if (!pipeline->command[i]) { sysdebug(1); for (j = 0; j < i; j++) free (pipeline->command[j]); free(pipeline->command); free (pipeline); return NULL; } } pipeline->ground = FOREGROUND; pipeline->file_in[0] = '\0'; pipeline->file_out[0] = '\0'; return pipeline; }
int runcmd (const char *command, int *result, int *io) /* ToDO: const char* */ { int pid, status; int aux, i, tmp_result; char *args[RCMD_MAXARGS], *p, *cmd; FILE *fp=NULL; tmp_result = 0; /* Parse arguments to obtain an argv vector. */ cmd = malloc ((strlen (command)+1) * sizeof(char)); sysfail (!cmd, -1); p = strcpy (cmd, command); i=0; args[i++] = strtok (cmd, RCMD_DELIM); while ((i<RCMD_MAXARGS) && (args[i++] = strtok (NULL, RCMD_DELIM))); i--; /* Create a subprocess. */ pid = fork(); sysfail (pid<0, -1); if (pid>0) /* Caller process (parent). */ { aux = wait (&status); sysfail (aux<0, -1); /* Collect termination mode. */ if (WIFEXITED(status)){ tmp_result |= NORMTERM; fp = fopen("check.txt","r"); if(fp == NULL){ tmp_result |= WEXITSTATUS(status); tmp_result |= EXECOK; } else{ tmp_result |= EXECFAILSTATUS & RETSTATUS; fclose(fp); remove("check.txt"); } } } else /* Subprocess (child) */ { aux = execvp (args[0], args); if(aux <= -1){ fp = fopen("check.txt","w"); fclose(fp); } exit (EXECFAILSTATUS); } if (result) *result = tmp_result; free (p); return pid; /* Only parent reaches this point. */ }
void outerr(void) { sysfail("write to stdout",errno); }
static void printusage(void) { static const struct optioninfo *const all_optiontables[]= { global_options, perquery_options, 0 }; const struct optioninfo *const *oiap, *oip=0; int maxsopt, maxlopt, l; maxsopt= maxlopt= 0; for (oiap=all_optiontables; *oiap; oiap++) { for (oip=*oiap; oip->type != ot_end; oip++) { if (oip->type == ot_funcarg) continue; if (oip->sopt) { l= strlen(oip->sopt); if (l>maxsopt) maxsopt= l; } if (oip->lopt) { l= strlen(oip->lopt); if (oip->type == ot_flag && !oip->value) l+= 3; if (l>maxlopt) maxlopt= l; } } } fputs("usage: adnshost [global-opts] [query-opts] query-domain\n" " [[query-opts] query-domain ...]\n" " adnshost [global-opts] [query-opts] -f|--pipe\n", stdout); for (oiap=all_optiontables; *oiap; oiap++) { putchar('\n'); for (oip=*oiap; oip->type != ot_end; oip++) { switch (oip->type) { case ot_flag: if (!oip->value) { if (oip->sopt) { printf(" +%-*s --no-%-*s %s\n", maxsopt, oip->sopt, maxlopt-2, oip->lopt, oip->desc); } else { printf(" --no-%-*s %s\n", maxlopt+maxsopt+1, oip->lopt, oip->desc); } break; } case ot_value: case ot_func: /* fall through */ if (oip->sopt) { printf(" -%-*s --%-*s %s\n", maxsopt, oip->sopt, maxlopt+1, oip->lopt, oip->desc); } else { printf(" --%-*s %s\n", maxlopt+maxsopt+3, oip->lopt, oip->desc); } break; case ot_funcarg: if (oip->sopt) { l= (maxlopt + maxsopt - 9 - (strlen(oip->sopt) + strlen(oip->lopt) + 2*strlen(oip->argdesc))); printf(" -%s<%s> / --%s <%s>%*s%s\n", oip->sopt, oip->argdesc, oip->lopt, oip->argdesc, l>2 ? l : 2, "", oip->desc); } else { l= (maxlopt + maxsopt + 1 - (strlen(oip->lopt) + strlen(oip->argdesc))); printf(" --%s <%s>%*s%s\n", oip->lopt, oip->argdesc, l>2 ? l : 2, "", oip->desc); } break; case ot_funcarg2: assert(!oip->sopt); l= (maxlopt + maxsopt - 2 - (strlen(oip->lopt) + strlen(oip->argdesc) + strlen(oip->argdesc2))); printf(" --%s <%s> <%s>%*s%s\n", oip->lopt, oip->argdesc, oip->argdesc2, l>2 ? l : 2, "", oip->desc); break; case ot_desconly: printf("%s\n", oip->desc); break; default: abort(); } } } printf("\nEscaping domains which might start with `-':\n" " - %-*s Next argument is a domain, but more options may follow\n", maxlopt+maxsopt+3, "<domain>"); fputs("\n" "Query domains should always be quoted according to master file format.\n" "\n" "For binary options, --FOO and --no-FOO are opposites, as are\n" "-X and +X. In each case the default is the one not listed.\n" "Per query options stay set a particular way until they are reset,\n" "whether they appear on the command line or on stdin.\n" "All global options must preceed the first query domain.\n" "\n" "With -f, the input should be lines with either an option, possibly\n" "with a value argument (separated from the option by a space if it's a long\n" "option), or a domain (possibly preceded by a hyphen and a space to\n" "distinguish it from an option).\n" "\n" "Output format is master file format without class or TTL by default:\n" " [<owner>] [<ttl>] [<type>] <data>\n" "or if the <owner> domain refers to a CNAME and --show-cname is on\n" " [<owner>] [<ttl>] CNAME <cname>\n" " [<cname>] [<ttl>] <type> <data>\n" "When a query fails you get an error message to stderr (with --fmt-simple).\n" "Specify --fmt-inline for lines like this (broken here for readability):\n" " ; failed <statustype> <statusnum> <statusabbrev> \\\n" " [<owner>] [<ttl>] [<cname>] \"<status string>\"\n" "If you use --fmt-asynch, which is the default for --asynch,\n" "each answer (success or failure) is preceded by a line\n" " <id> <nrrs> <statustype> <statusnum> <statusabbrev> \\\n" " [<owner>] [<ttl>] [<cname>] \"<status string>\"\n" "where <nrrs> is the number of RRs that follow and <cname> will be `$' or\n" "the CNAME target; the CNAME indirection and error formats above are not used.\n" "\n" "Exit status:\n" " 0 all went well\n" " 1-6 at least one query failed with statustype:\n" " 1 localfail )\n" " 2 remotefail ) temporary errors\n" " 3 tempfail __)_________________\n" " 4 misconfig )\n" " 5 misquery ) permanent errors\n" " 6 permfail )\n" " 10 system trouble\n" " 11 usage problems\n" "\n" "Query types (see adns.h; default is addr):\n" " ns soa ptr mx rp addr - enhanced versions\n" " cname hinfo txt - types with only one version\n" " a ns- soa- ptr- mx- rp- - _raw versions\n" "Default is addr, or ptr for -i/--ptr queries\n", stdout); if (ferror(stdout)) sysfail("write usage message",errno); }
void of_help(const struct optioninfo *oi, const char *arg, const char *arg2) { printusage(); if (fclose(stdout)) sysfail("finish writing output",errno); quitnow(0); }