int main(int argc, char *argv[]) { #ifdef WINDOWS HANDLE hchild; int child; #else pid_t child; #endif int rc; int arg_offs = 1; const char *outfile = NULL; const char *pidfile = NULL; if (argc < 2) { return usage(argv[0]); } while (argv[arg_offs][0] == '-') { if (strcmp(argv[arg_offs], "-env") == 0) { if (argc <= arg_offs + 2) return usage(argv[0]); #if VERBOSE fprintf(stderr, "setting env var \"%s\" to \"%s\"\n", argv[arg_offs + 1], argv[arg_offs + 2]); #endif #ifdef WINDOWS rc = SetEnvironmentVariable(argv[arg_offs + 1], argv[arg_offs + 2]); #else rc = setenv(argv[arg_offs + 1], argv[arg_offs + 2], 1 /*overwrite*/); #endif if (rc != 0 || strcmp(mygetenv(argv[arg_offs + 1]), argv[arg_offs + 2]) != 0) { fprintf(stderr, "error in setenv of \"%s\" to \"%s\"\n", argv[arg_offs + 1], argv[arg_offs + 2]); fprintf(stderr, "setenv returned %d\n", rc); fprintf(stderr, "env var \"%s\" is now \"%s\"\n", argv[arg_offs + 1], mygetenv(argv[arg_offs + 1])); exit(1); } arg_offs += 3; } else if (strcmp(argv[arg_offs], "-out") == 0) { if (argc <= arg_offs + 1) return usage(argv[0]); outfile = argv[arg_offs + 1]; arg_offs += 2; } else if (strcmp(argv[arg_offs], "-pid") == 0) { if (argc <= arg_offs + 1) return usage(argv[0]); pidfile = argv[arg_offs + 1]; arg_offs += 2; } else { return usage(argv[0]); } if (argc - arg_offs < 1) return usage(argv[0]); } #ifdef UNIX child = fork(); if (child < 0) { perror("ERROR on fork"); } else if (child == 0) { /* redirect std{out,err} */ redirect_stdouterr(outfile); execv(argv[arg_offs], argv + arg_offs /*include app*/); fprintf(stderr, "execv of %s FAILED", argv[arg_offs]); exit(1); } /* else, parent, and we continue below */ if (pidfile == NULL) printf("%d\n", child); #else /* redirect std{out,err} */ redirect_stdouterr(outfile); /* Do we want _P_DETACH instead of _P_NOWAIT? _P_DETACH doesn't return the * child handle though. */ hchild = (HANDLE)_spawnv(_P_NOWAIT, argv[arg_offs], argv + arg_offs /*include app*/); if (hchild == INVALID_HANDLE_VALUE) { fprintf(stderr, "_spawnv of %s FAILED", argv[arg_offs]); exit(1); } child = process_id_from_handle(hchild); #endif if (pidfile != NULL) { FILE *f = fopen(pidfile, "w"); if (f == NULL) { perror("open pidfile failed"); exit(1); } fprintf(f, "%d\n", child); fclose(f); } return 0; }
/* * Read a word and advance pointer. * Also processes quoting, variable substituting, and \ escapes. */ char *getword(char **s) { unsigned int len; int f; int idx = 0; const char *t = *s; int sawesc = 0; int sawq = 0; const char *env; char envbuf[32]; if (**s == 0) return NULL; for (len = 0; ; len++) { if (sawesc && t[len]) { sawesc = 0; if (t[len] <= '7' && t[len] >= '0') { buf_wr(idx, 0); for (f = 0; f < 4 && len < bufsize() && t[len] <= '7' && t[len] >= '0'; f++) buf_wr(idx, 8 * buf_rd(idx) + t[len++] - '0'); if (buf_rd(idx) == 0) buf_wr(idx, NULL_CHARACTER); idx++; len--; continue; } switch (t[len]) { case 'r': buf_wr(idx++, '\r'); break; case 'n': buf_wr(idx++, '\n'); break; case 'b': buf_wr(idx++, '\b'); break; case 'a': buf_wr(idx++, '\a'); break; case 'f': buf_wr(idx++, '\f'); break; case 'c': buf_wr(idx++, SKIP_NEWLINE); break; default: buf_wr(idx++, t[len]); break; } sawesc = 0; continue; } if (t[len] == '\\') { sawesc = 1; continue; } if (t[len] == '"') { if (sawq == 1) { sawq = 0; len++; break; } sawq = 1; continue; } if (t[len] == '$' && t[len + 1] == '(') { for(f = len; t[f] && t[f] != ')'; f++) ; if (t[f] == ')') { strncpy(envbuf, &t[len + 2], f - len - 2); envbuf[f - len - 2] = 0; len = f; env = mygetenv(envbuf); if (env == NULL) env = ""; while (*env) buf_wr(idx++, *env++); continue; } } /* ^ prefix for control chars - jl 3.2002 */ if (sawq == 1 && t[len] == '^' && t[len + 1] != 0) { char c = toupper(t[len + 1]); if (c >= 'A' && c <= '_') { len++; buf_wr(idx++, c - 'A' + 1); continue; } } if ((!sawq && (t[len] == ' ' || t[len] == '\t')) || t[len] == 0) break; buf_wr(idx++, t[len]); } buf_wr(idx, 0); *s += len; skipspace(s); if (sawesc || sawq) syntaxerr(_("(word contains ESC or quote)")); return buf(); }
int file68_init(int argc, char **argv) { char tmp[1024]; option68_t * opt; if (init) { const int i = init & 3; const char *message[4] = { "clean","initialized","shutdowning","initializing" }; error68("file68: init error -- *%s*", message[i]); argc = -1; goto out_no_init; } init = 3; /* Options */ option68_init(); /* Zlib */ istream68_z_init(); /* Curl */ istream68_curl_init(); /* Xiph AO */ istream68_ao_init(); /* Init resource */ rsc68_init(); /* Loader */ file68_loader_init(); option68_append(opts,sizeof(opts)/sizeof(*opts)); argc = option68_parse(argc, argv, 1); /* Check for --sc68-no-debug */ opt = option68_get("no-debug", 1); if (opt && opt->val.num) { /* Remove all debug messages whatsoever. */ msg68_set_handler(0); } /* Check for --sc68-asid=off|safe|force */ if (opt = option68_get("asid",1), opt) { if (!strcmp68(opt->val.str,"no")) aSIDify = 0; else if (!strcmp68(opt->val.str,"safe")) aSIDify = 1; else if (!strcmp68(opt->val.str,"force")) aSIDify = 2; else msg68_notice("file68: ignore invalid mode for --sc68-asid -- *%s*\n", opt->val.str); } /* Check for --sc68-debug= */ /* postpone: at this point most debug features have not been created yet. it is pretty much useless to set the mask right now. It will be done after all inits. */ #if 0 opt = option68_get("debug", 1); if (op) { debugmsg68_mask = opt->val.num; } #endif /* Get share path from registry */ opt = option68_get("data", 0); if (opt) { /* Get data path from registry */ if (!option68_isset(opt)) { char * e; const char path[] = "Resources"; e = get_reg_path(registry68_rootkey(REGISTRY68_LMK), "SOFTWARE/sashipa/sc68/Install_Dir", tmp, sizeof(tmp)); if (e && (e+sizeof(path) < tmp+sizeof(tmp))) { memcpy(e, path, sizeof(path)); option68_set(opt,tmp); } } /* Setup new data path */ if (option68_isset(opt)) { rsc68_set_share(opt->val.str); #if 0 /* not needed anynore since option68 properly alloc strings */ if (opt->val.str == tmp) option68_unset(opt); /* Must release tmp ! */ #endif } } /* Get user path */ opt = option68_get("home", 0); if (opt) { /* Get user path from HOME */ if (!option68_isset(opt)) { const char path[] = "/.sc68"; const char * env = mygetenv("HOME"); if(env && strlen(env)+sizeof(path) < sizeof(tmp)) { strncpy(tmp,env,sizeof(tmp)); strcat68(tmp,path,sizeof(tmp)); /* $$$ We should test if this directory actually exists */ option68_set(opt,tmp); } } /* Get user path from registry */ if (!option68_isset(opt)) { char * e; const char path[] = "sc68"; e = get_reg_path(registry68_rootkey(REGISTRY68_CUK), "Volatile Environment/APPDATA", tmp, sizeof(tmp)); if (e && (e+sizeof(path) < tmp+sizeof(tmp))) { memcpy(e, path, sizeof(path)); option68_set(opt,tmp); } } /* Setup new user path */ if (option68_isset(opt)) { rsc68_set_user(opt->val.str); if (opt->val.str == tmp) option68_unset(opt); /* Must release tmp ! */ } } /* Setup new music path */ opt = option68_get("music", 1); if (opt) { rsc68_set_music(opt->val.str); } /* Setup new remote path */ opt = option68_get("remote", 1); if (opt) { rsc68_set_remote_music(opt->val.str); } init = 1; out_no_init: return argc; }
void mouseinit(void) { char *term; /* see if this is emacsterm or viterm */ term = mygetenv("TERM", ""); if (strcmp(term, "emacsterm") == 0 || strcmp(term, "viterm") == 0) { emacsviterm = YES; mouse = YES; } /* the MOUSE enviroment variable is for 5620 terminal programs that have mouse support but the TERM environment variable is the same as a terminal without a mouse, such as myx */ else if (strcmp(mygetenv("MOUSE", ""), "myx") == 0) { mouse = YES; } #if UNIXPC else if (strcmp(term,"s4") == 0 || strcmp(term,"s120") == 0 || strcmp(term,"s90") == 0) { int retval; struct uwdata uwd; /* Window data structure */ struct umdata umd; /* Mouse data structure */ /* Ask for character size info */ retval = ioctl(1,WIOCGETD,&uwd); if(retval || uwd.uw_hs <= 0 || uwd.uw_vs <= 0) { /************************************************** * something wrong with the kernel, so fake it... **************************************************/ if(!strcmp(term,"s4")) { uw_hs = 9; uw_vs = 12; } else { uw_hs = 6; uw_vs = 10; } } else { /* Kernel is working and knows about this font */ uw_hs = uwd.uw_hs; uw_vs = uwd.uw_vs; } /************************************************** * Now turn on mouse reporting so we can actually * make use of all this stuff. **************************************************/ if((retval = ioctl(1,WIOCGETMOUSE,&umd)) != -1) { umd.um_flags= MSDOWN+MSUP; ioctl(1,WIOCSETMOUSE,&umd); } unixpcmouse = YES; } #endif if (mouse == YES) { loadmenu(mainmenu); } }
int main(int argc, char **argv) { int envc; /* environment argument count */ char **envv; /* environment argument list */ FILE *names; /* name file pointer */ int oldnum; /* number in old cross-ref */ char path[PATHLEN + 1]; /* file path */ FILE *oldrefs; /* old cross-reference file */ char *s; int c, i; pid_t pid; /* save the command name for messages */ argv0 = basename(argv[0]); /* get the current directory for build() and line-oriented P command */ if (mygetwd(currentdir) == NULL) { (void) fprintf(stderr, "cscope: warning: cannot get current directory name\n"); (void) strcpy(currentdir, "<unknown>"); } /* initialize any view path; (saves time since currendir is known) */ vpinit(currentdir); dbvpndirs = vpndirs; /* number of directories in database view path */ /* directories (including current) in database view path */ dbvpdirs = vpdirs; /* the first source directory is the current directory */ sourcedir("."); /* read the environment */ editor = mygetenv("EDITOR", EDITOR); editor = mygetenv("VIEWER", editor); /* use viewer if set */ home = getenv("HOME"); shell = mygetenv("SHELL", SHELL); tmpdir = mygetenv("TMPDIR", TMPDIR); /* increment nesting depth */ cscopedepth = atoi(mygetenv("CSCOPEDEPTH", "0")); (void) sprintf(path, "CSCOPEDEPTH=%d", ++cscopedepth); (void) putenv(stralloc(path)); if ((s = getenv("CSCOPEOPTIONS")) != NULL) { /* parse the environment option string */ envc = 1; envv = mymalloc(sizeof (char *)); s = strtok(stralloc(s), OPTSEPS); while (s != NULL) { envv = myrealloc(envv, ++envc * sizeof (char *)); envv[envc - 1] = stralloc(s); s = strtok((char *)NULL, OPTSEPS); } /* set the environment options */ options(envc, envv); } /* set the command line options */ options(argc, argv); /* create the temporary file names */ pid = getpid(); (void) sprintf(temp1, "%s/cscope%d.1", tmpdir, (int)pid); (void) sprintf(temp2, "%s/cscope%d.2", tmpdir, (int)pid); /* if running in the foreground */ if (signal(SIGINT, SIG_IGN) != SIG_IGN) { /* cleanup on the interrupt and quit signals */ (void) signal(SIGINT, myexit); (void) signal(SIGQUIT, myexit); } /* cleanup on the hangup signal */ (void) signal(SIGHUP, myexit); /* if the database path is relative and it can't be created */ if (reffile[0] != '/' && access(".", WRITE) != 0) { /* if the database may not be up-to-date or can't be read */ (void) sprintf(path, "%s/%s", home, reffile); if (isuptodate == NO || access(reffile, READ) != 0) { /* put it in the home directory */ reffile = stralloc(path); (void) sprintf(path, "%s/%s", home, invname); invname = stralloc(path); (void) sprintf(path, "%s/%s", home, invpost); invpost = stralloc(path); (void) fprintf(stderr, "cscope: symbol database will be %s\n", reffile); } } /* if the cross-reference is to be considered up-to-date */ if (isuptodate == YES) { if ((oldrefs = vpfopen(reffile, "r")) == NULL) { cannotopen(reffile); exit(1); } /* * get the crossref file version but skip the current * directory */ if (fscanf(oldrefs, "cscope %d %*s", &fileversion) != 1) { (void) fprintf(stderr, "cscope: cannot read file version from file %s\n", reffile); exit(1); } if (fileversion >= 8) { /* override these command line options */ compress = YES; invertedindex = NO; /* see if there are options in the database */ for (;;) { /* no -q leaves multiple blanks */ while ((c = getc(oldrefs)) == ' ') { ; } if (c != '-') { (void) ungetc(c, oldrefs); break; } switch (c = getc(oldrefs)) { case 'c': /* ASCII characters only */ compress = NO; break; case 'q': /* quick search */ invertedindex = YES; (void) fscanf(oldrefs, "%ld", &totalterms); break; case 'T': /* truncate symbols to 8 characters */ dbtruncated = YES; truncatesyms = YES; break; } } initcompress(); /* seek to the trailer */ if (fscanf(oldrefs, "%ld", &traileroffset) != 1) { (void) fprintf(stderr, "cscope: cannot read trailer offset from " "file %s\n", reffile); exit(1); } if (fseek(oldrefs, traileroffset, 0) != 0) { (void) fprintf(stderr, "cscope: cannot seek to trailer in " "file %s\n", reffile); exit(1); } } /* * read the view path for use in converting relative paths to * full paths * * note: don't overwrite vp[n]dirs because this can cause * the wrong database index files to be found in the viewpath */ if (fileversion >= 13) { if (fscanf(oldrefs, "%d", &dbvpndirs) != 1) { (void) fprintf(stderr, "cscope: cannot read view path size from " "file %s\n", reffile); exit(1); } if (dbvpndirs > 0) { dbvpdirs = mymalloc( dbvpndirs * sizeof (char *)); for (i = 0; i < dbvpndirs; ++i) { if (fscanf(oldrefs, "%s", path) != 1) { (void) fprintf(stderr, "cscope: cannot read view " "path from file %s\n", reffile); exit(1); } dbvpdirs[i] = stralloc(path); } } } /* skip the source and include directory lists */ skiplist(oldrefs); skiplist(oldrefs); /* get the number of source files */ if (fscanf(oldrefs, "%d", &nsrcfiles) != 1) { (void) fprintf(stderr, "cscope: cannot read source file size from " "file %s\n", reffile); exit(1); } /* get the source file list */ srcfiles = mymalloc(nsrcfiles * sizeof (char *)); if (fileversion >= 9) { /* allocate the string space */ if (fscanf(oldrefs, "%d", &oldnum) != 1) { (void) fprintf(stderr, "cscope: cannot read string space size " "from file %s\n", reffile); exit(1); } s = mymalloc(oldnum); (void) getc(oldrefs); /* skip the newline */ /* read the strings */ if (fread(s, oldnum, 1, oldrefs) != 1) { (void) fprintf(stderr, "cscope: cannot read source file names " "from file %s\n", reffile); exit(1); } /* change newlines to nulls */ for (i = 0; i < nsrcfiles; ++i) { srcfiles[i] = s; for (++s; *s != '\n'; ++s) { ; } *s = '\0'; ++s; } /* if there is a file of source file names */ if (namefile != NULL && (names = vpfopen(namefile, "r")) != NULL || (names = vpfopen(NAMEFILE, "r")) != NULL) { /* read any -p option from it */ while (fscanf(names, "%s", path) == 1 && *path == '-') { i = path[1]; s = path + 2; /* for "-Ipath" */ if (*s == '\0') { /* if "-I path" */ (void) fscanf(names, "%s", path); s = path; } switch (i) { case 'p': /* file path components */ /* to display */ if (*s < '0' || *s > '9') { (void) fprintf(stderr, "cscope: -p option " "in file %s: " "missing or " "invalid numeric " "value\n", namefile); } dispcomponents = atoi(s); } } (void) fclose(names); } } else { for (i = 0; i < nsrcfiles; ++i) { if (fscanf(oldrefs, "%s", path) != 1) { (void) fprintf(stderr, "cscope: cannot read source file " "name from file %s\n", reffile); exit(1); } srcfiles[i] = stralloc(path); } } (void) fclose(oldrefs); } else { /* get source directories from the environment */ if ((s = getenv("SOURCEDIRS")) != NULL) { sourcedir(s); } /* make the source file list */ srcfiles = mymalloc(msrcfiles * sizeof (char *)); makefilelist(); if (nsrcfiles == 0) { (void) fprintf(stderr, "cscope: no source files found\n"); printusage(); exit(1); } /* get include directories from the environment */ if ((s = getenv("INCLUDEDIRS")) != NULL) { includedir(s); } /* add /usr/include to the #include directory list */ includedir("/usr/include"); /* initialize the C keyword table */ initsymtab(); /* create the file name(s) used for a new cross-reference */ (void) strcpy(path, reffile); s = basename(path); *s = '\0'; (void) strcat(path, "n"); ++s; (void) strcpy(s, basename(reffile)); newreffile = stralloc(path); (void) strcpy(s, basename(invname)); newinvname = stralloc(path); (void) strcpy(s, basename(invpost)); newinvpost = stralloc(path); /* build the cross-reference */ initcompress(); build(); if (buildonly == YES) { exit(0); } } opendatabase(); /* * removing a database will not release the disk space if a cscope * process has the file open, so a project may want unattended cscope * processes to exit overnight, including their subshells and editors */ if (noacttime) { (void) signal(SIGALRM, timedout); (void) alarm(noacttime); } /* * if using the line oriented user interface so cscope can be a * subprocess to emacs or samuel */ if (linemode == YES) { if (*pattern != '\0') { /* do any optional search */ if (search() == YES) { while ((c = getc(refsfound)) != EOF) { (void) putchar(c); } } } if (onesearch == YES) { myexit(0); } for (;;) { char buf[PATLEN + 2]; if (noacttime) { (void) alarm(noacttime); } (void) printf(">> "); (void) fflush(stdout); if (fgets(buf, sizeof (buf), stdin) == NULL) { myexit(0); } /* remove any trailing newline character */ if (*(s = buf + strlen(buf) - 1) == '\n') { *s = '\0'; } switch (*buf) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* samuel only */ field = *buf - '0'; (void) strcpy(pattern, buf + 1); (void) search(); (void) printf("cscope: %d lines\n", totallines); while ((c = getc(refsfound)) != EOF) { (void) putchar(c); } break; case 'c': /* toggle caseless mode */ case ctrl('C'): if (caseless == NO) { caseless = YES; } else { caseless = NO; } egrepcaseless(caseless); break; case 'r': /* rebuild database cscope style */ case ctrl('R'): freefilelist(); makefilelist(); /* FALLTHROUGH */ case 'R': /* rebuild database samuel style */ rebuild(); (void) putchar('\n'); break; case 'C': /* clear file names */ freefilelist(); (void) putchar('\n'); break; case 'F': /* add a file name */ (void) strcpy(path, buf + 1); if (infilelist(path) == NO && vpaccess(path, READ) == 0) { addsrcfile(path); } (void) putchar('\n'); break; case 'P': /* print the path to the files */ if (prependpath != NULL) { (void) puts(prependpath); } else { (void) puts(currentdir); } break; case 'q': /* quit */ case ctrl('D'): case ctrl('Z'): myexit(0); default: (void) fprintf(stderr, "cscope: unknown command '%s'\n", buf); break; } } /* NOTREACHED */ } /* pause before clearing the screen if there have been error messages */ if (errorsfound == YES) { errorsfound = NO; askforreturn(); } (void) signal(SIGINT, SIG_IGN); /* ignore interrupts */ (void) signal(SIGPIPE, SIG_IGN); /* | command can cause pipe signal */ /* initialize the curses display package */ (void) initscr(); /* initialize the screen */ setfield(); /* set the initial cursor position */ entercurses(); (void) keypad(stdscr, TRUE); /* enable the keypad */ dispinit(); /* initialize display parameters */ putmsg(""); /* clear any build progress message */ display(); /* display the version number and input fields */ /* do any optional search */ if (*pattern != '\0') { atfield(); /* move to the input field */ (void) command(ctrl('A')); /* search */ display(); /* update the display */ } else if (reflines != NULL) { /* read any symbol reference lines file */ (void) readrefs(reflines); display(); /* update the display */ } for (;;) { if (noacttime) { (void) alarm(noacttime); } atfield(); /* move to the input field */ /* exit if the quit command is entered */ if ((c = mygetch()) == EOF || c == ctrl('D') || c == ctrl('Z')) { break; } /* execute the commmand, updating the display if necessary */ if (command(c) == YES) { display(); } } /* cleanup and exit */ myexit(0); /* NOTREACHED */ return (0); }