pathname.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:3k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Convert relative to absolute pathnames
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "dirutil.h"
  7. static void crunch(char *buf,char *path);
  8. /* Given a working directory and an arbitrary pathname, resolve them into
  9.  * an absolute pathname. Memory is allocated for the result, which
  10.  * the caller must free
  11.  */
  12. char *
  13. pathname(cd,path)
  14. char *cd; /* Current working directory */
  15. char *path; /* Pathname argument */
  16. {
  17. register char *buf;
  18. #ifdef MSDOS
  19. char *cp,c;
  20. char *tbuf;
  21. int tflag = 0;
  22. #endif
  23. if(cd == NULL || path == NULL)
  24. return NULL;
  25. #ifdef MSDOS
  26. /* If path has any backslashes, make a local copy with them
  27.  * translated into forward slashes
  28.  */
  29. if(strchr(path,'\') != NULL){
  30. tflag = 1;
  31. cp = tbuf = mallocw(strlen(path));
  32. while((c = *path++) != ''){
  33. if(c == '\')
  34. *cp++ = '/';
  35. else
  36. *cp++ = c;
  37. }
  38. *cp = '';
  39. path = tbuf;
  40. }
  41. #endif
  42. /* Strip any leading white space on args */
  43. while(*cd == ' ' || *cd == 't')
  44. cd++;
  45. while(*path == ' ' || *path == 't')
  46. path++;
  47. /* Allocate and initialize output buffer; user must free */
  48. buf = mallocw((unsigned)strlen(cd) + strlen(path) + 10); /* fudge factor */
  49. buf[0] = '';
  50. /* Interpret path relative to cd only if it doesn't begin with "/" */
  51. if(path[0] != '/')
  52. crunch(buf,cd);
  53. crunch(buf,path);
  54. /* Special case: null final path means the root directory */
  55. if(buf[0] == ''){
  56. buf[0] = '/';
  57. buf[1] = '';
  58. }
  59. #ifdef MSDOS
  60. if(tflag)
  61. free(tbuf);
  62. #endif
  63. return buf;
  64. }
  65. /* Process a path name string, starting with and adding to
  66.  * the existing buffer
  67.  */
  68. static void
  69. crunch(buf,path)
  70. char *buf;
  71. register char *path;
  72. {
  73. register char *cp;
  74. cp = buf + strlen(buf); /* Start write at end of current buffer */
  75. /* Now start crunching the pathname argument */
  76. for(;;){
  77. /* Strip leading /'s; one will be written later */
  78. while(*path == '/')
  79. path++;
  80. if(*path == '')
  81. break; /* no more, all done */
  82. /* Look for parent directory references, either at the end
  83.  * of the path or imbedded in it
  84.  */
  85. if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
  86. /* Hop up a level */
  87. if((cp = strrchr(buf,'/')) == NULL)
  88. cp = buf; /* Don't back up beyond root */
  89. *cp = ''; /* In case there's another .. */
  90. path += 2; /* Skip ".." */
  91. while(*path == '/') /* Skip one or more slashes */
  92. path++;
  93. /* Look for current directory references, either at the end
  94.  * of the path or imbedded in it
  95.  */
  96. } else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
  97. /* "no op" */
  98. path++; /* Skip "." */
  99. while(*path == '/') /* Skip one or more slashes */
  100. path++;
  101. } else {
  102. /* Ordinary name, copy up to next '/' or end of path */
  103. *cp++ = '/';
  104. while(*path != '/' && *path != '')
  105. *cp++ = *path++;
  106. }
  107. }
  108. *cp++ = '';
  109. }