URIScheme makeAbsoluteURI(Sit S, const char* uri, const char* base, Str& absolute) { FiveStr u_parts, b_parts; Bool u_defined[5], u_any = FALSE; Str scheme; // first, break up the URIs into their 5 components splitURI(uri, u_parts); splitURI(base, b_parts); // set u_defined[i] to TRUE if the i-th uri component is nonvoid for (int i = 0; i < 5; i++) u_any = (Bool) ((u_defined[i] = (Bool) !u_parts[i].isEmpty()) || u_any); if (!u_any) // all components empty: the reference is to the current document { splitURI(base,u_parts); u_parts[U_QUERY].empty(); // query and fragment are NOT inherited from base u_parts[U_FRAG].empty(); } else // not all components are empty { if (!u_defined[U_SCHEME]) // undefined scheme { u_parts[U_SCHEME] = b_parts[U_SCHEME]; // inherit scheme from base if (!u_defined[U_AUTH]) // undefined authority { u_parts[U_AUTH] = b_parts[U_AUTH]; // inherit authority from base if (!isSlash(u_parts[U_PATH][0])) // path is relative joinPaths(u_parts[U_PATH], b_parts[U_PATH]); // append path to base path // query and fragment stay as they are in 'uri' } } else { scheme = u_parts[U_SCHEME]; URIScheme uri_scheme = schemeToURI_(S, scheme); if (uri_scheme == URI_EXTENSION) { absolute = uri; return URI_EXTENSION; } // scheme defined, check for paths not starting with '/' if (!u_defined[U_AUTH] && !isSlash(u_parts[U_PATH][0])) u_parts[U_PATH] = Str("/") + u_parts[U_PATH]; } } DStr joined = absolute; joinURI(joined, u_parts, FALSE); // join all components into a URI for return (no scheme) scheme = u_parts[U_SCHEME]; absolute = (scheme + ":") + joined; return schemeToURI_(S, scheme); }
/* A normal Win32 pathname contains no duplicate slashes, except possibly * for a UNC prefix, and does not end with a slash. It may be the empty * string. Normalized Win32 pathnames have the convenient property that * the length of the prefix almost uniquely identifies the type of the path * and whether it is absolute or relative: * * 0 relative to both drive and directory * 1 drive-relative (begins with '\\') * 2 absolute UNC (if first char is '\\'), * else directory-relative (has form "z:foo") * 3 absolute local pathname (begins with "z:\\") */ static int normalizePrefix(const char* path, int len, char* sb, int* sbLen) { char c; int src = 0; while ((src < len) && isSlash(path[src])) src++; if ((len - src >= 2) && isLetter(c = path[src]) && path[src + 1] == ':') { /* Remove leading slashes if followed by drive specifier. This hack is necessary to support file URLs containing drive specifiers (e.g., "file://c:/path"). As a side effect, "/c:/path" can be used as an alternative to "c:/path". */ sb[(*sbLen)++] = c; sb[(*sbLen)++] = ':'; src += 2; } else { src = 0; if ((len >= 2) && isSlash(path[0]) && isSlash(path[1])) { /* UNC pathname: Retain first slash; leave src pointed at second slash so that further slashes will be collapsed into the second slash. The result will be a pathname beginning with "\\\\" followed (most likely) by a host name. */ src = 1; sb[(*sbLen)++] = slash; } } return src; }
void TFilePath::setPath(string path) { bool isUncName = false; // elimino i '//', './' e '/' finali; raddrizzo gli slash 'storti'. // se il path comincia con "<alpha>:" aggiungo uno slash int length = path.length(); int pos = 0; if (path.length() >= 2 && isalpha(path[0]) && path[1] == ':') { m_path.append(path, 0, 2); pos = 2; if (path.length() == 2 || !isSlash(path[pos])) m_path.append(1, slash); } #ifdef WIN32 else // se si tratta di un path in formato UNC e' del tipo "\\\\MachineName" if (path.length() >= 3 && path[0] == '\\' && path[1] == '\\' && isalpha(path[2])) { isUncName = true; m_path.append(path, 0, 3); pos = 3; } #endif for (; pos < length; pos++) if (path[pos] == '.') { pos++; if (pos >= length) { if (pos > 1) m_path.append(1, '.'); } else if (!isSlash(path[pos])) m_path.append(path, pos - 1, 2); else { while (pos + 1 < length && isSlash(path[pos + 1])) pos++; } } else if (isSlash(path[pos])) { do pos++; while (pos < length && isSlash(path[pos])); pos--; m_path.append(1, slash); } else { m_path.append(1, path[pos]); } // rimuovo l'eventuale '/' finale (a meno che m_path == "/" o m_path == // "<letter>:\" // oppure sia UNC (Windows only) ) if (!(m_path.length() == 1 && m_path[0] == slash || m_path.length() == 3 && isalpha(m_path[0]) && m_path[1] == ':' && m_path[2] == slash) && m_path.length() > 1 && m_path[m_path.length() - 1] == slash) m_path.erase(m_path.length() - 1, 1); if (isUncName && m_path.find_last_of('\\') == 1) // e' indicato solo il nome della macchina... m_path.append(1, slash); }
static char * SkipAddress(char *s, int *count) { char *base = s; int done; if (*count) { if (isComma(*s)) { flt_putc(*s++); } else { return s; } } if (isdigit(CharOf(*s))) { while (isdigit(CharOf(*s))) s++; flt_puts(base, (int) (s - base), Number_attr); } else if (*s == '$') { flt_puts(s++, 1, Literal_attr); } else if (isSlash(*s)) { if (*s == BACKSLASH) { flt_puts(s++, 1, Action_attr); } s = SkipPattern(s, &done, 0); } else { s = SkipError(s); } *count += 1; return s; }
// cerca l'ultimo '/' o '\'. Se non c'e' ritorna -1 // di modo che la sottostringa che parte da getLastSlash() + 1 e' nome.frame.tipo inline int getLastSlash(const string &path) { int i; for (i = path.length() - 1; i >= 0 && !isSlash(path[i]); i--) { } return i; }
static std::string removeLeadingSlash(const std::string& s) { if (s.length() > 0 && isSlash(s[0])) { return s.substr(1); } else { return s; } }
static void check_href(DavDeleteXMLParser::DavxDeleteXmlIntern & par, const std::string & name){ std::string _href(name); rtrim(_href, isSlash()); // remove trailing slash std::string::reverse_iterator it = std::find(_href.rbegin(), _href.rend(), '/'); if( it == _href.rend()){ par._last_filename.assign(_href); }else{ par._last_filename.assign(it.base(), _href.end()); } DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_XML, " href/filename parsed -> {} ", par._last_filename.c_str() ); }
char * fleaf_delim(const char *path) { #ifdef SYS_UNIX return strrchr(path, '/'); #endif #if defined(vms) || defined(MSDOS) char *s = path + strlen(path); while (s-- != path) { if (isSlash(*s)) return s; } return 0; #endif }
void splitURI(const char *uri, FiveStr &parts) { const char *rest; char c; for (int i = 0; i < 5; i++) parts[i].empty(); RF( uri && *uri ); // extract the scheme part of the URI if (!splitBy(rest = uri, ":", parts[U_SCHEME])) parts[U_SCHEME].empty(); // if "//" follows, extract the authority part c = 'A'; // marks the absence of auth if (isSlash(*rest) && isSlash(rest[1])) RF( c = splitBy(rest += 2, slashes"?#", parts[U_AUTH]) ); if (isSlash(c) || c == 'A') // extract the path RF( c = splitBy(rest -= (isSlash(c)), "?#", parts[U_PATH]) ); //query and fragment if (c == '?') // extract the query RF( c = splitBy(rest, "#", parts[U_QUERY]) ); // copy the fragment parts[U_FRAG] = (char *) rest; };
int is_subpath(char *name_ref, char *name_tst) { size_t l_ref = strlen(name_ref); size_t l_tst = strlen(name_tst); if (l_ref < l_tst && isSlash(name_tst[l_ref]) && !strncmp(name_ref, name_tst, l_ref)) return (int) l_ref + 1; if (l_ref == l_tst && !strcmp(name_ref, name_tst)) return (int) l_ref; return -1; }
Bool cutLast(Str& path, int howmany) { Str temp = path; char *p = (char*) temp; int slashCount = 0, i; for (i = temp.length() - 1; i >= 0; i--) { if (isSlash(p[i])) slashCount++; if (slashCount == howmany) break; }; if (i >= 0) path.nset(p, i+1); else path.empty(); return (Bool)(i >= 0); };
void sccslast(const char *working, /* working directory (absolute) */ const char *path, /* pathname to check (may be relative) */ const char **vers_, time_t * date_, const char **lock_) { Stat_t sbfr; char fname[MAXPATHLEN]; char local[MAXPATHLEN]; char *dname = sccs_dir(working, path); int is_sccs; char *s, *the_leaf; *lock_ = "?"; *vers_ = "?"; *date_ = 0; if (strlen(dname) >= sizeof(fname)) return; if (strlen(path) >= sizeof(local)) return; path = strcpy(local, path); /* * If the file resides in an sccs-directory and its name begins with * an appropriate prefix (lowercase letter followed by '.' and then * more characters) assume it is an sccs file. */ if ((s = fleaf_delim(the_leaf = local)) != NULL) { /* determine directory from path */ *(the_leaf = s) = EOS; if ((s = fleaf(local)) == NULL) s = local; is_sccs = sameleaf(s, dname) || sameleaf(dname, s); *the_leaf++ = PATH_SLASH; } else if ((s = fleaf(working)) != NULL) { is_sccs = sameleaf(s, dname); } else { return; /* illegal input: give up */ } /* * If the file is an sccs-file, we wish to show the file-modification * date in the Z-field since this will highlight better files which are * not checked-in, or which are not checked out (possibly obsolete). */ if (is_sccs /* the_leaf => filename */ && (strlen(the_leaf) > LEN_PREFIX) && (isalpha((int) *the_leaf) && islower((int) *the_leaf)) && (the_leaf[1] == '.')) { char xx = *the_leaf; *the_leaf = 's'; (void) strcpy(fname, path); *the_leaf = xx; trySCCS(fname, vers_, date_, lock_); if (*date_) { /* it was an ok sccs file */ /* look for checked-out file */ if (the_leaf != path) { pathcat(fname, working, the_leaf + LEN_PREFIX); } else { pathcat(fname, "../", the_leaf + LEN_PREFIX); } *date_ = 0; /* use actual modification-date! */ if (stat(fname, &sbfr) >= 0) { *date_ = sbfr.st_mtime; } return; } } /* * The file was not itself an sccs-file. Construct the name of an * sccs-file assuming the standard naming convention, and try again. * * If the value 'dname[]' from 'sccs_dir()' is not a relative path, * assume that SCCS_VAULT was set. */ if (the_leaf != path) { the_leaf[-1] = EOS; (void) strcpy(fname, path); } else { fname[0] = EOS; } if (isSlash(*dname) || *dname == '~') { (void) strcpy(fname, dname); } else if ((strlen(fname) + strlen(dname) + 3) < sizeof(fname)) { (void) pathcat(fname, fname, dname); } else { return; } if ((strlen(fname) + strlen(SCCS_PREFIX) + strlen(the_leaf) + 5) < sizeof(fname)) { (void) strcat(pathcat(fname, fname, SCCS_PREFIX), the_leaf); trySCCS(fname, vers_, date_, lock_); } }
static int HaveAddress(char *s) { return (isdigit(CharOf(*s)) || *s == '$' || isSlash(*s) || isComma(*s)); }
/* * Normalize the given pathname, whose length is len, starting at the given * offset; everything before this offset is already normal. */ static char* normalizePath(const char* path, int len, int off) { int src; char* sb; int sbLen; if (len == 0) return (char*)path; if (off < 3) off = 0; /* Avoid fencepost cases with UNC pathnames */ sb = (char*)malloc(len+1); sbLen = 0; if (off == 0) { /* Complete normalization, including prefix */ src = normalizePrefix(path, len, sb, &sbLen); } else { /* Partial normalization */ src = off; memcpy(sb+sbLen, path, off); sbLen += off; } /* Remove redundant slashes from the remainder of the path, forcing all slashes into the preferred slash */ while (src < len) { char c = path[src++]; if (isSlash(c)) { while ((src < len) && isSlash(path[src])) src++; if (src == len) { /* Check for trailing separator */ if ((sbLen == 2) && (sb[1] == ':')) { /* "z:\\" */ sb[sbLen++] = slash; break; } if (sbLen == 0) { /* "\\" */ sb[sbLen++] = slash; break; } if ((sbLen == 1) && (isSlash(sb[0]))) { /* "\\\\" is not collapsed to "\\" because "\\\\" marks the beginning of a UNC pathname. Even though it is not, by itself, a valid UNC pathname, we leave it as is in order to be consistent with the win32 APIs, which treat this case as an invalid UNC pathname rather than as an alias for the root directory of the current drive. */ sb[sbLen++] = slash; break; } /* Path does not denote a root directory, so do not append trailing slash */ break; } else { sb[sbLen++] = slash; } } else { sb[sbLen++] = c; } } sb[sbLen] = '\0'; return sb; }
char * trimpath(char *path, const char *cwd) { static char slash[] = {PATH_SLASH, EOS}; char *s, *d; /* * Convert this to an absolute path somehow */ if (isSlash(*path)) { ; } else if (*path) { char tmp[MAXPATHLEN]; if (strlen(cwd) < sizeof(tmp)) { d = strcpy(tmp, cwd); s = path; if (*s == '.') if (s[1] == EOS || isSlash(s[1])) s++; /* absorb "." */ d += strlen(tmp); if (((int) strlen(s) + 3 + (d - tmp)) < MAXPATHLEN) { if (!isSlash(d[-1])) /* add delim iff we need it */ (void) strcat(d, slash); (void) strcat(d, s); (void) strcpy(path, tmp); } } } /* * Trim out repeated path-delimiter marks */ for (s = d = path; *s; s++) { if (isSlash(*s)) { while (isSlash(s[1])) { s++; } } else if (*s == '.') { if (s > path && isSlash(s[-1])) { if (s[1] == EOS) { break; } else if (isSlash(s[1])) { s++; continue; } } } *d++ = *s; } /* * Trim trailing path-delimiter marks */ while (d > path + 1) { if (isSlash(d[-1])) { d--; } else { break; } } *d = EOS; /* * Trim out ".." constructs */ for (s = path; *s; s++) { if (s[0] == '.' && s[1] == '.') if ((s > path && isSlash(s[-1])) && (s[2] == EOS || isSlash(s[2]))) { d = s + 2; if (s > path) { s -= 2; while (s > path && !isSlash(*s)) { s--; } if (s == path && !*d) { s++; } } else if (*d) { s--; } while ((*s++ = *d++) != EOS) { ; } s = path; /* rescan */ } } return (path); }
void vsmcreate(int argc, char *argv[]) { TVSMHeader head; // VSM file header TVSMResource res; // resource char *fdir = NULL; // working directory char *fn = NULL; // target file name TCRC csum; // checksum int i; FILE *f; char *tmp, *tmp2; char ch; // command line parameters int vendor_id = -1; bool dont_load_header = false; bool dont_incl_footer = false; int ins_version = 0; unsigned short int version[4]; // process arguments passed by command line for (i=2; i<argc; i++) { // -vid if (strcasecmp(argv[i], "-vid") == 0) { // there is no argument after -vid if (i+1 >= argc) errexit("Wrong parameter format '-vid'"); sscanf(argv[++i], "%u", &vendor_id); } // -dh else if (strcasecmp(argv[i], "-dh") == 0) dont_load_header = true; // -df else if (strcasecmp(argv[i], "-df") == 0) dont_incl_footer = true; // -v else if (strcasecmp(argv[i], "-v") == 0) { if (i+1 >= argc) errexit("Wrong parameter format '-v'"); ins_version = 1; if (sscanf(argv[++i], "%hd.%hd.%hd.%hd", &version[3], &version[2], &version[1], &version[0]) != 4) errexit("Wrong parameter format '-v'\nShould be '-v a.b.c.d'"); } // File or directory name else if (i+2 >= argc) { if (fdir == NULL) fdir = argv[i]; else fn = argv[i]; } // Incorrect parameter else { printf("Unknown argument: %s\n", argv[i]); errexit("Wrong parameter format"); } } // Directory not specified if (fdir == NULL) errexit("Input folder not specified"); // Target file not specified - generating filename from input folder if (fn == NULL) { fn = new char[strlen(fdir) + 5]; strcpy(fn, fdir); if (isSlash(fn)) fn[strlen(fn) -1] = '\0'; strcat(fn, ".vsm"); } // End directory path by '\' char: if (isSlash(fdir) == 0) { tmp = new char[strlen(fdir) + 2]; strcpy(tmp, fdir); strcat(tmp, "\\"); fdir = tmp; } // File information printf("Input folder: %s\n", fdir); printf("Output file: %s\n", fn); // Load header if (dont_load_header == false) { // open file tmp = new char[strlen(fdir) + 12]; strcpy(tmp, fdir); strcat(tmp, "header.bin"); i = fload(tmp, &head, sizeof(head)); delete [] tmp; // file doesn't exists if (i < 0) errexit("\nCan't open file 'header.bin'.\n" "Use '-dh' switch to generate default header"); else if (i != sizeof(head)) errexit("\nIncorrect file 'header.bin'.\n" "Use '-dh' switch to generate default header"); } // generate header else { memset(&head, 0, sizeof(head)); head.signature = VSMSignature; } // change vendor id if (vendor_id >= 0) head.vendor_id = vendor_id; // change version number if (ins_version) { for (i=0; i<4; i++) head.version[i] = version[i]; } // Show header info printf("Vendor ID: %d\n\n", head.vendor_id); // Check if output file already exists if (FileExist(fn)) { printf("File %s already exist. Overwrite? (y/N)\n\n", fn); ch = getch(); if ((ch != 'y') && (ch != 'Y')) exit(0); } // Open output file f = fopen(fn, "wb"); if (f == NULL) errexit("Can't create output file!"); // Write header puts("writing header"); if (fwrite(&head, sizeof(head), 1, f) <= 0) { fclose(f); errexit("Write error!"); } // Prepare to listing files tmp = new char[8192]; strcpy(tmp, fdir); tmp2 = tmp + strlen(tmp); strcat(tmp, "res*"); TFileList fl; char *fname = FLFindFirst(&fl, tmp); res.data = new char[VSMMaxResSize+1]; csum.newCRC32(); head.ressize = 0; // Write file while (fname) { i = ParseResName(fname); // given file is not a resource file - skip if (i < 0) continue; res.id = i; printf("writing resource 0x%04x from %s\n", res.id, fname); // read resource file strcpy(tmp2, fname); i = fload(tmp, res.data, VSMMaxResSize+1); if (i < 0) errexit("Can't read resource file!"); res.size = i; if (i >= VSMMaxResSize+1) errexit("Resource file is too big!"); // write to output file if (fwrite(&res, RHSIZE, 1, f) <= 0) errexit("Write error!"); if (fwrite(res.data, res.size, 1, f) <= 0) errexit("Write error!"); csum.add(&res, RHSIZE); csum.add(res.data, res.size); head.ressize += RHSIZE + res.size; // make sure that file end up with even address if (head.ressize & 1) { if (fwrite("\0", 1, 1, f) <= 0) errexit("Write error!"); head.ressize++; csum.add(0); } fname = FLFind(&fl); } // Writing footer if (dont_incl_footer == false) { // footer address (divided by 4) i = head.ressize & 3; if (i) { i = 4 - i; if (fwrite("\0\0\0", i, 1, f) <= 0) errexit("Write error!"); } // load footer strcpy(tmp2, "footer.bin"); i = fload(tmp, res.data, VSMMaxResSize); // if footer exists if (i != -1) { puts("writing footer"); // can't read footer.bin if (i < 0) errexit("\nCan't open file 'footer.bin'.\n" "Use '-df' switch if you don't need footer"); // footer.bin length is 0 if (i == 0) printf("\nFile 'footer.bin' is empty."); // write footer and check for errors else if (fwrite(res.data, i, 1, f) <= 0) errexit("Write error!"); } } // Update header checksum head.checksum = csum.getCRC32() ^ 0xffffffff; puts("updating header (checksum and resources size)\n"); fseek(f, 0, SEEK_SET); if (fwrite(&head, sizeof(head), 1, f) <= 0) errexit("Write error!"); fclose(f); fileinfo(&head, head.checksum); delete [] tmp; delete [] res.data; } // void vsmcreate(int argc, char *argv[])