DOS 3.30 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
5.5 KiB

5 years ago
  1. #include "types.h"
  2. #include "dpb.h"
  3. #include <dos.h>
  4. /* #define KANJI TRUE */
  5. /* return FALSE if drive is valid AND the path is not a prefix of a non-root
  6. * current directory.
  7. */
  8. char fPathErr(p)
  9. char *p ;
  10. {
  11. char buf[MAXARG] ;
  12. int d ;
  13. #ifdef KANJI
  14. char *p1;
  15. #endif
  16. if (p[1] == ':')
  17. d = *p-'A'+1 ;
  18. else
  19. d = 0 ;
  20. if (curdir(buf, d) == -1) /* drive is invalid => error */
  21. return(TRUE) ;
  22. if (strlen(buf) == 3) /* current directory is root => OK */
  23. return(FALSE) ;
  24. if (strpre(p, buf)) {
  25. #ifdef KANJI
  26. p1 = p;
  27. while (*p1 != NULL) {
  28. if(testkanj(*p1 & 0xFF))
  29. p1 += 2 ;
  30. else
  31. if((*p1++ == '\\') && (*p1 == NULL))
  32. return(TRUE) ;
  33. }
  34. #else
  35. if (p[strlen(p)-1] == '\\') /* prefix matched, prefix had...*/
  36. return(TRUE) ; /* ...trailing / => valid ... */
  37. /* ...prefix => ERROR */
  38. #endif
  39. d = buf[strlen(p)] ;
  40. if (d == 0 || d == '\\') /* prefix matched,... */
  41. return(TRUE) ; /* ...prefix had no trailing /, */
  42. /* ...next char was / => ... */
  43. /* ...valid prefix => ERROR */
  44. } ;
  45. return(FALSE) ; /* drive letter good and not valid prefix => OK */
  46. }
  47. strpre(pre, tot)
  48. char *pre;
  49. char *tot;
  50. {
  51. return(!strncmp(pre, tot, strlen(pre)));
  52. }
  53. Fatal(p)
  54. char *p ;
  55. {
  56. printf("%s\n", p) ;
  57. exit(1) ;
  58. }
  59. ffirst(pb, attr, pfbuf)
  60. char *pb ;
  61. int attr ;
  62. struct findType *pfbuf ;
  63. {
  64. union REGS regs ;
  65. /* set DMA to point to buffer */
  66. regs.h.ah = 0x1A ;
  67. regs.x.dx = (unsigned) pfbuf ;
  68. intdos (&regs, &regs) ;
  69. /* perform system call */
  70. regs.h.ah = 0x4E ;
  71. regs.x.cx = attr ;
  72. regs.x.dx = (unsigned) pb ;
  73. intdos (&regs, &regs) ;
  74. return (regs.x.cflag ? -1 : 0) ;
  75. }
  76. fnext (pfbuf)
  77. struct findType *pfbuf;
  78. {
  79. union REGS regs;
  80. /* set DMA to point to buffer */
  81. regs.h.ah = 0x1A;
  82. regs.x.dx = (unsigned) pfbuf;
  83. intdos (&regs, &regs);
  84. /* perform system call */
  85. regs.h.ah = 0x4F;
  86. intdos (&regs, &regs);
  87. return (regs.x.cflag ? -1 : 0) ;
  88. }
  89. char *strbscan(str, class)
  90. char *str ;
  91. char *class ;
  92. {
  93. char *p ;
  94. char *strpbrk() ;
  95. p = strpbrk(str, class) ;
  96. return((p == NULL) ? (str + strlen(str)) : p) ;
  97. }
  98. /* curdir.c - return text of current directory for a particular drive */
  99. curdir (dst, drive)
  100. char *dst ;
  101. int drive ;
  102. {
  103. union REGS regs ;
  104. *dst++ = PathChr ;
  105. regs.h.ah = 0x47 ;
  106. regs.h.dl = drive ;
  107. regs.x.si = (unsigned) dst ;
  108. intdos (&regs, &regs) ;
  109. return(regs.x.cflag ? -1 : 0) ;
  110. }
  111. /*
  112. rootpath
  113. */
  114. /*** rootpath -- convert a pathname argument to root based cannonical form
  115. *
  116. * rootpath determines the current directory, appends the path argument (which
  117. * may affect which disk the current directory is relative to), and qualifies
  118. * "." and ".." references. The result is a complete, simple, path name with
  119. * drive specifier.
  120. *
  121. * If the relative path the user specifies does not include a drive spec., the
  122. * default drive will be used as the base. (The default drive will never be
  123. * changed.)
  124. *
  125. * entry: relpath -- pointer to the pathname to be expanded
  126. * fullpath -- must point to a working buffer, see warning
  127. * exit: fullpath -- the full path which results
  128. * return: true if an error occurs, false otherwise
  129. *
  130. * calls: curdir, getdrv
  131. *
  132. * warning: fullpath must point to a working buffer large enough to hold the
  133. * longest possible relative path argument plus the longest possible
  134. * current directory path.
  135. *
  136. */
  137. int rootpath(relpath, fullpath)
  138. char *relpath ;
  139. char *fullpath ;
  140. {
  141. int drivenum ;
  142. char tempchar, getdrv() ;
  143. register char *lead, *follow ;
  144. char *p1, *p2;
  145. /* extract drive spec */
  146. drivenum = getdrv() ;
  147. if ((*relpath != NULL) && (relpath[1] == COLON)) {
  148. drivenum = toupper(*relpath) - 'A' ;
  149. relpath += 2 ;
  150. }
  151. fullpath[0] = (char) ('A' + drivenum) ;
  152. fullpath[1] = COLON ;
  153. /* append relpath to fullpath/base */
  154. if (*relpath == PathChr) {
  155. /* relpath starts at base */
  156. strcpy(fullpath+2, relpath) ;
  157. }
  158. else {
  159. /* must get base path first */
  160. if (curdir(fullpath+2, drivenum+1))
  161. return(TRUE) ; /* terrible error */
  162. if ((*relpath != ASCNULL) && (strlen(fullpath) > 3))
  163. strcat(fullpath, "\\") ;
  164. strcat(fullpath, relpath) ;
  165. }
  166. /* convert path to cannonical form */
  167. lead = fullpath ;
  168. while(*lead != ASCNULL) {
  169. /* mark next path segment */
  170. follow = lead ;
  171. lead = (char *) strpbrk(follow+1, "\\") ;
  172. if (lead == NULL)
  173. lead = fullpath + strlen(fullpath) ;
  174. tempchar = *lead ;
  175. if (tempchar == PathChr)
  176. tempchar = BACKSLASH ; /* make breaks uniform */
  177. *lead = ASCNULL ;
  178. /* "." segment? */
  179. if (strcmp(follow+1, ".") == 0) {
  180. *lead = tempchar ;
  181. strcpy(follow, lead) ; /* remove "." segment */
  182. lead = follow ;
  183. }
  184. /* ".." segment? */
  185. else if (strcmp(follow+1, "..") == 0) {
  186. *lead = tempchar ;
  187. tempchar = *follow ;
  188. *follow = NULL ;
  189. p2 = fullpath - 1 ;
  190. while(*(p2=strbscan(p1=p2+1,"\\")) != NULL) ;
  191. /* p1 now points to the start of the previous element */
  192. *follow = tempchar ;
  193. if(p1 == fullpath)
  194. return(TRUE) ; /* tried to .. the root */
  195. follow = p1 - 1 ; /* follow points to path sep */
  196. strcpy(follow, lead) ; /* remove ".." segment */
  197. lead = follow ;
  198. }
  199. /* normal segment */
  200. else
  201. *lead = tempchar ;
  202. }
  203. if (strlen(fullpath) == 2) /* 'D:' or some such */
  204. strcat(fullpath, "\\") ;
  205. /* shift to upper case */
  206. strupr(fullpath) ;
  207. return(FALSE) ;
  208. }
  209. /* getdrv - return current drive as a character */
  210. char getdrv()
  211. {
  212. union REGS regs ;
  213. regs.h.ah = CURDISK ; /* Function 0x19 */
  214. intdos (&regs, &regs) ;
  215. return(regs.h.al) ;
  216. }
  217.