Path: utzoo!attcan!uunet!mcvax!ukc!reading!onion!cf-cm!sme From: sme@computing-maths.cardiff.ac.uk (Simon Elliott) Newsgroups: comp.sys.ibm.pc Subject: Re: How to add to PATH on the fly? Summary: pathed.c - you asked for it Message-ID: <468@cf-cm.UUCP> Date: 11 Jul 88 11:39:24 GMT References: <688@crcmar.crc.uucp> <604@arctic.nprdc.arpa> Organization: Univ. Coll. Cardiff, Cardiff, WALES, UK. Lines: 221 Here is pathed.c, containing instructions for its surrounding batch files for various versions of DOS. I compiled it with Turbo C v1.0. It uses strtok, which some compilers' libraries don't have. ------------------------8x----------------------8x------------------------ /* * pathed.c - core of path editor * * Written by Simon Elliott (...!mcvax!ukc!cf-cm!sme). * Version 1.0 10/11/87. * * As you will see from the usage message, this claims to be PATHEDIT. * Actually, this program is called from within a batch file, and * should be called PATHED, or something. I keep PATHED.EXE _and_ * PATHEDIT.BAT in my \BATCH directory, which is _always_ in my * PATH. (PATHED.EXE is the only non-.BAT in \BATCH) * * Here is PATHEDIT.BAT for Dos < 3.30: * echo off * pathed %1 %2 >\$$$.bat * if not errorlevel 1 \$$$ * * and for Dos >= 3.30: * @echo off * pathed %1 %2 >$$$.bat * if not errorlevel 1 call $$$.bat * del $$$.bat >nul * * usage: * pathedit -a d:\path appends to current path * pathedit -d d:\path deletes d:\path from current path * pathedit -i d:\path inserts d:\path before current path * pathedit -3 d:\path adds/moves d:\path to 3rd place in path */ #includechar pathbuffer[129]; /* delete() builds path command here */ char *pathcommand = "path "; char *getenv(), *strcpy(), *strchr(), *strtok(); void usage(), pathcmd2(), delete(), moveto(); main(ac, av) int ac; char *av[]; { register char *current; if (ac < 3 || *av[1] != '-' && *av[1] != '/') usage(); current = getenv("PATH"); strupr(av[2]); switch (av[1][1]) { case 'A': case 'a': /* append */ if (current) pathcmd2(current, av[2]); else pathcmd2(av[2], ""); break; case 'D': case 'd': /* delete */ if (current) delete(av[2], current); break; case 'I': case 'i': /* insert */ if (current) pathcmd2(av[2], current); else pathcmd2(av[2], ""); break; default: /* numeric position or bad option */ if (!isnumber(++av[1])) usage(); /* first delete any of the target component */ if (current) { strcpy(pathbuffer, current); delete(av[2], current); } else pathbuffer[0] = '\0'; /* pathbuffer contains the path after deletions */ moveto(atoi(av[1]), av[2], pathbuffer); } /* make batch report what the path is now */ fputs("path\n", stdout); exit(0); } void usage() { fputs("usage: pathedit [-a] [-d] [-i] [-N] d:\\path\n", stderr); exit(1); } /* * pathcmd2() - output a path command with one or possibly two strings. */ void pathcmd2(first, second) char *first, *second; { fputs(pathcommand, stdout); fputs(first, stdout); if (*second) { putchar(';'); fputs(second, stdout); } putchar('\n'); } /* * delete() - delete occurences of deletion from well formed PATH string * pointed to by source. */ void delete(deletion, source) char *deletion, *source; { register char *dest; register int first; char *component; first = 1; dest = pathbuffer; /* look for ';' separator until end of string */ component = strtok(source, ";"); while (component != NULL) { if (strcmp(deletion, component)) { /* no match - copy component to dest */ if (!first) *dest++ = ';'; strcpy(dest, component); dest = strchr(dest, '\0'); first = 0; } /* advance the component of the PATH */ component = strtok(NULL, ";"); } if (first) { fputs("set PATH=", stdout); pathbuffer[0] = '\0'; } else { fputs(pathcommand, stdout); fputs(pathbuffer, stdout); } putchar('\n'); } /* * moveto() - move PATH component insertion to position posn in well-formed * PATH string pointed to by source. * we assume that insertion has been deleted already in the source string. */ void moveto(posn, insertion, source) register int posn; /* desired position of insertion in source */ char *insertion, *source; { register int curposn; int needsemi; fputs(pathcommand, stdout); curposn = 1; /* number positions from 1 */ needsemi = 0; /* start off not needing a semicolon */ while (curposn < posn && *source) { if (';' == *source) { ++curposn; needsemi = 0; } else needsemi = 1; putchar(*source++); } /* need this kludge because we could be at 1st or last position */ if (needsemi) putchar(';'); fputs(insertion, stdout); if (*source) { /* write out rest of source (if any) */ putchar(';'); fputs(source, stdout); } putchar('\n'); } isnumber(str) char *str; { char c; while (c = *str++) /* assign */ if (c < '0' || c > '9') return 0; return 1; } ------------------------8x----------------------8x------------------------ If you find this half as useful as I do, then just remember - I'm finding it twice as useful as you are, so there! Enjoy! -- Simon Elliott Microcomputer Support University College Cardiff Computer Centre, Cardiff, Wales ...!mcvax!ukc!cf-cm!sme