ohair@425: /* ohair@425: * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. ohair@425: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohair@425: * ohair@425: * This code is free software; you can redistribute it and/or modify it ohair@425: * under the terms of the GNU General Public License version 2 only, as ohair@425: * published by the Free Software Foundation. Oracle designates this ohair@425: * particular file as subject to the "Classpath" exception as provided ohair@425: * by Oracle in the LICENSE file that accompanied this code. ohair@425: * ohair@425: * This code is distributed in the hope that it will be useful, but WITHOUT ohair@425: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohair@425: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohair@425: * version 2 for more details (a copy is included in the LICENSE file that ohair@425: * accompanied this code). ohair@425: * ohair@425: * You should have received a copy of the GNU General Public License version ohair@425: * 2 along with this work; if not, write to the Free Software Foundation, ohair@425: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohair@425: * ohair@425: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@425: * or visit www.oracle.com if you need additional information or have any ohair@425: * questions. ohair@425: */ ohair@425: ohair@425: #include ohair@425: #include ohair@425: #include ohair@425: #include ohair@425: #include ohair@425: ohair@425: /* ohair@425: * Test if pos points to /cygdrive/_/ where _ can ohair@425: * be any character. ohair@425: */ ohair@425: int is_cygdrive_here(int pos, char *in, int len) ohair@425: { ohair@425: // Length of /cygdrive/c/ is 12 ohair@425: if (pos+12 > len) return 0; ohair@425: if (in[pos+11]=='/' && ohair@425: in[pos+9]=='/' && ohair@425: in[pos+8]=='e' && ohair@425: in[pos+7]=='v' && ohair@425: in[pos+6]=='i' && ohair@425: in[pos+5]=='r' && ohair@425: in[pos+4]=='d' && ohair@425: in[pos+3]=='g' && ohair@425: in[pos+2]=='y' && ohair@425: in[pos+1]=='c' && ohair@425: in[pos+0]=='/') { ohair@425: return 1; ohair@425: } ohair@425: return 0; ohair@425: } ohair@425: ohair@425: /* ohair@425: * Replace /cygdrive/_/ with _:/ ohair@425: * Works in place since drive letter is always ohair@425: * shorter than /cygdrive/ ohair@425: */ ohair@425: char *replace_cygdrive(char *in) ohair@425: { ohair@425: int len = strlen(in); ohair@425: char *out = malloc(len+1); ohair@425: int i,j; ohair@425: ohair@425: if (len < 12) { ohair@425: strcpy(out, in); ohair@425: return out; ohair@425: } ohair@425: for (i = 0, j = 0; i *bl) { ohair@425: *bl *= 2; ohair@425: *b = realloc(*b, *bl); ohair@425: } ohair@425: memcpy(*b+*u, add, addlen); ohair@425: *u += addlen; ohair@425: } ohair@425: ohair@425: /* ohair@425: * Creates a new string from in where the first occurance of sub is ohair@425: * replaced by rep. ohair@425: */ ohair@425: char *replace_substring(char *in, char *sub, char *rep) ohair@425: { ohair@425: int in_len = strlen(in); ohair@425: int sub_len = strlen(sub); ohair@425: int rep_len = strlen(rep); ohair@425: char *out = malloc(in_len - sub_len + rep_len + 1); ohair@425: char *p; ohair@425: ohair@425: if (!(p = strstr(in, sub))) { ohair@425: // If sub isn't a substring of in, just return in. ohair@425: return in; ohair@425: } ohair@425: ohair@425: // Copy characters from beginning of in to start of sub. ohair@425: strncpy(out, in, p - in); ohair@425: out[p - in] = '\0'; ohair@425: ohair@425: sprintf(out + (p - in), "%s%s", rep, p + sub_len); ohair@425: ohair@425: return out; ohair@425: } ohair@425: ohair@425: char *files_to_delete[1024]; ohair@425: int num_files_to_delete = 0; ohair@425: ohair@425: char *fix_at_file(char *in) ohair@425: { ohair@425: char *tmpdir; ohair@425: char name[2048]; ohair@425: char *atname; ohair@425: char *buffer; ohair@425: size_t buflen=65536; ohair@425: size_t used=0; ohair@425: size_t len; ohair@425: int rc; ohair@425: FILE *atout; ohair@425: FILE *atin; ohair@425: char block[2048]; ohair@425: size_t blocklen; ohair@425: char *fixed; ohair@425: ohair@425: atin = fopen(in+1, "r"); ohair@425: if (atin == NULL) { ohair@425: fprintf(stderr, "Could not read at file %s\n", in+1); ohair@425: exit(-1); ohair@425: } ohair@425: ohair@425: tmpdir = getenv("TMP"); ohair@425: if (tmpdir == NULL) { ohair@425: tmpdir = "c:/cygwin/tmp"; ohair@425: } ohair@425: _snprintf(name, sizeof(name), "%s\\atfile_XXXXXX", tmpdir); ohair@425: ohair@425: rc = _mktemp_s(name, strlen(name)+1); ohair@425: if (rc) { ohair@425: fprintf(stderr, "Could not create temporary file name for at file!\n"); ohair@425: exit(-1); ohair@425: } ohair@425: ohair@425: atout = fopen(name, "w"); ohair@425: if (atout == NULL) { ohair@425: fprintf(stderr, "Could open temporary file for writing! %s\n", name); ohair@425: exit(-1); ohair@425: } ohair@425: ohair@425: buffer = malloc(buflen); ohair@425: while((blocklen = fread(block,1,sizeof(block),atin)) > 0) { ohair@425: append(&buffer, &buflen, &used, block, blocklen); ohair@425: } ohair@425: buffer[used] = 0; ohair@425: fixed = replace_cygdrive(buffer); ohair@425: fwrite(fixed, strlen(fixed), 1, atout); ohair@425: fclose(atin); ohair@425: fclose(atout); ohair@425: free(fixed); ohair@425: free(buffer); ohair@425: files_to_delete[num_files_to_delete] = malloc(strlen(name)+1); ohair@425: strcpy(files_to_delete[num_files_to_delete], name); ohair@425: num_files_to_delete++; ohair@425: atname = malloc(strlen(name)+2); ohair@425: atname[0] = '@'; ohair@425: strcpy(atname+1, name); ohair@425: return atname; ohair@425: } ohair@425: ohair@425: int main(int argc, char **argv) ohair@425: { ohair@425: STARTUPINFO si; ohair@425: PROCESS_INFORMATION pi; ohair@425: unsigned short rc; ohair@425: ohair@425: char *new_at_file; ohair@425: char *old_at_file; ohair@425: char *line; ohair@425: int i; ohair@425: DWORD exitCode; ohair@425: ohair@425: if (argc<2) { ohair@425: fprintf(stderr, "Usage: uncygdrive.exe /cygdrive/c/WINDOWS/notepad.exe /cygdrive/c/x/test.txt"); ohair@425: exit(0); ohair@425: } ohair@425: ohair@425: line = replace_cygdrive(strstr(GetCommandLine(), argv[1])); ohair@425: ohair@425: for (i=1; i%s<\n", line); ohair@425: } ohair@425: ohair@425: ZeroMemory(&si,sizeof(si)); ohair@425: si.cb=sizeof(si); ohair@425: ZeroMemory(&pi,sizeof(pi)); ohair@425: ohair@425: rc = CreateProcess(NULL, ohair@425: line, ohair@425: 0, ohair@425: 0, ohair@425: TRUE, ohair@425: 0, ohair@425: 0, ohair@425: 0, ohair@425: &si, ohair@425: &pi); ohair@425: if(!rc) ohair@425: { ohair@425: //Could not start process; ohair@425: fprintf(stderr, "Could not start process!\n"); ohair@425: exit(-1); ohair@425: } ohair@425: ohair@425: WaitForSingleObject(pi.hProcess,INFINITE); ohair@425: GetExitCodeProcess(pi.hProcess,&exitCode); ohair@425: ohair@425: if (getenv("DEBUG_UNCYGDRIVE") != NULL) { ohair@425: for (i=0; i