common/src/uncygdrive.c

Mon, 16 Jul 2012 22:41:04 +0100

author
vinnie
date
Mon, 16 Jul 2012 22:41:04 +0100
changeset 465
0562a97bd601
parent 425
e1830598f0b7
permissions
-rw-r--r--

6880559: Enable PKCS11 64-bit windows builds
Reviewed-by: valeriep

ohair@425 1 /*
ohair@425 2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
ohair@425 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@425 4 *
ohair@425 5 * This code is free software; you can redistribute it and/or modify it
ohair@425 6 * under the terms of the GNU General Public License version 2 only, as
ohair@425 7 * published by the Free Software Foundation. Oracle designates this
ohair@425 8 * particular file as subject to the "Classpath" exception as provided
ohair@425 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@425 10 *
ohair@425 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@425 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@425 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@425 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@425 15 * accompanied this code).
ohair@425 16 *
ohair@425 17 * You should have received a copy of the GNU General Public License version
ohair@425 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@425 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@425 20 *
ohair@425 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@425 22 * or visit www.oracle.com if you need additional information or have any
ohair@425 23 * questions.
ohair@425 24 */
ohair@425 25
ohair@425 26 #include <Windows.h>
ohair@425 27 #include <io.h>
ohair@425 28 #include <stdio.h>
ohair@425 29 #include <string.h>
ohair@425 30 #include <malloc.h>
ohair@425 31
ohair@425 32 /*
ohair@425 33 * Test if pos points to /cygdrive/_/ where _ can
ohair@425 34 * be any character.
ohair@425 35 */
ohair@425 36 int is_cygdrive_here(int pos, char *in, int len)
ohair@425 37 {
ohair@425 38 // Length of /cygdrive/c/ is 12
ohair@425 39 if (pos+12 > len) return 0;
ohair@425 40 if (in[pos+11]=='/' &&
ohair@425 41 in[pos+9]=='/' &&
ohair@425 42 in[pos+8]=='e' &&
ohair@425 43 in[pos+7]=='v' &&
ohair@425 44 in[pos+6]=='i' &&
ohair@425 45 in[pos+5]=='r' &&
ohair@425 46 in[pos+4]=='d' &&
ohair@425 47 in[pos+3]=='g' &&
ohair@425 48 in[pos+2]=='y' &&
ohair@425 49 in[pos+1]=='c' &&
ohair@425 50 in[pos+0]=='/') {
ohair@425 51 return 1;
ohair@425 52 }
ohair@425 53 return 0;
ohair@425 54 }
ohair@425 55
ohair@425 56 /*
ohair@425 57 * Replace /cygdrive/_/ with _:/
ohair@425 58 * Works in place since drive letter is always
ohair@425 59 * shorter than /cygdrive/
ohair@425 60 */
ohair@425 61 char *replace_cygdrive(char *in)
ohair@425 62 {
ohair@425 63 int len = strlen(in);
ohair@425 64 char *out = malloc(len+1);
ohair@425 65 int i,j;
ohair@425 66
ohair@425 67 if (len < 12) {
ohair@425 68 strcpy(out, in);
ohair@425 69 return out;
ohair@425 70 }
ohair@425 71 for (i = 0, j = 0; i<len;) {
ohair@425 72 if (is_cygdrive_here(i, in, len)) {
ohair@425 73 out[j++] = in[i+10];
ohair@425 74 out[j++] = ':';
ohair@425 75 i+=11;
ohair@425 76 } else {
ohair@425 77 out[j] = in[i];
ohair@425 78 i++;
ohair@425 79 j++;
ohair@425 80 }
ohair@425 81 }
ohair@425 82 out[j] = 0;
ohair@425 83 return out;
ohair@425 84 }
ohair@425 85
ohair@425 86 void append(char **b, size_t *bl, size_t *u, char *add, size_t addlen)
ohair@425 87 {
ohair@425 88 while ( (addlen+*u+1) > *bl) {
ohair@425 89 *bl *= 2;
ohair@425 90 *b = realloc(*b, *bl);
ohair@425 91 }
ohair@425 92 memcpy(*b+*u, add, addlen);
ohair@425 93 *u += addlen;
ohair@425 94 }
ohair@425 95
ohair@425 96 /*
ohair@425 97 * Creates a new string from in where the first occurance of sub is
ohair@425 98 * replaced by rep.
ohair@425 99 */
ohair@425 100 char *replace_substring(char *in, char *sub, char *rep)
ohair@425 101 {
ohair@425 102 int in_len = strlen(in);
ohair@425 103 int sub_len = strlen(sub);
ohair@425 104 int rep_len = strlen(rep);
ohair@425 105 char *out = malloc(in_len - sub_len + rep_len + 1);
ohair@425 106 char *p;
ohair@425 107
ohair@425 108 if (!(p = strstr(in, sub))) {
ohair@425 109 // If sub isn't a substring of in, just return in.
ohair@425 110 return in;
ohair@425 111 }
ohair@425 112
ohair@425 113 // Copy characters from beginning of in to start of sub.
ohair@425 114 strncpy(out, in, p - in);
ohair@425 115 out[p - in] = '\0';
ohair@425 116
ohair@425 117 sprintf(out + (p - in), "%s%s", rep, p + sub_len);
ohair@425 118
ohair@425 119 return out;
ohair@425 120 }
ohair@425 121
ohair@425 122 char *files_to_delete[1024];
ohair@425 123 int num_files_to_delete = 0;
ohair@425 124
ohair@425 125 char *fix_at_file(char *in)
ohair@425 126 {
ohair@425 127 char *tmpdir;
ohair@425 128 char name[2048];
ohair@425 129 char *atname;
ohair@425 130 char *buffer;
ohair@425 131 size_t buflen=65536;
ohair@425 132 size_t used=0;
ohair@425 133 size_t len;
ohair@425 134 int rc;
ohair@425 135 FILE *atout;
ohair@425 136 FILE *atin;
ohair@425 137 char block[2048];
ohair@425 138 size_t blocklen;
ohair@425 139 char *fixed;
ohair@425 140
ohair@425 141 atin = fopen(in+1, "r");
ohair@425 142 if (atin == NULL) {
ohair@425 143 fprintf(stderr, "Could not read at file %s\n", in+1);
ohair@425 144 exit(-1);
ohair@425 145 }
ohair@425 146
ohair@425 147 tmpdir = getenv("TMP");
ohair@425 148 if (tmpdir == NULL) {
ohair@425 149 tmpdir = "c:/cygwin/tmp";
ohair@425 150 }
ohair@425 151 _snprintf(name, sizeof(name), "%s\\atfile_XXXXXX", tmpdir);
ohair@425 152
ohair@425 153 rc = _mktemp_s(name, strlen(name)+1);
ohair@425 154 if (rc) {
ohair@425 155 fprintf(stderr, "Could not create temporary file name for at file!\n");
ohair@425 156 exit(-1);
ohair@425 157 }
ohair@425 158
ohair@425 159 atout = fopen(name, "w");
ohair@425 160 if (atout == NULL) {
ohair@425 161 fprintf(stderr, "Could open temporary file for writing! %s\n", name);
ohair@425 162 exit(-1);
ohair@425 163 }
ohair@425 164
ohair@425 165 buffer = malloc(buflen);
ohair@425 166 while((blocklen = fread(block,1,sizeof(block),atin)) > 0) {
ohair@425 167 append(&buffer, &buflen, &used, block, blocklen);
ohair@425 168 }
ohair@425 169 buffer[used] = 0;
ohair@425 170 fixed = replace_cygdrive(buffer);
ohair@425 171 fwrite(fixed, strlen(fixed), 1, atout);
ohair@425 172 fclose(atin);
ohair@425 173 fclose(atout);
ohair@425 174 free(fixed);
ohair@425 175 free(buffer);
ohair@425 176 files_to_delete[num_files_to_delete] = malloc(strlen(name)+1);
ohair@425 177 strcpy(files_to_delete[num_files_to_delete], name);
ohair@425 178 num_files_to_delete++;
ohair@425 179 atname = malloc(strlen(name)+2);
ohair@425 180 atname[0] = '@';
ohair@425 181 strcpy(atname+1, name);
ohair@425 182 return atname;
ohair@425 183 }
ohair@425 184
ohair@425 185 int main(int argc, char **argv)
ohair@425 186 {
ohair@425 187 STARTUPINFO si;
ohair@425 188 PROCESS_INFORMATION pi;
ohair@425 189 unsigned short rc;
ohair@425 190
ohair@425 191 char *new_at_file;
ohair@425 192 char *old_at_file;
ohair@425 193 char *line;
ohair@425 194 int i;
ohair@425 195 DWORD exitCode;
ohair@425 196
ohair@425 197 if (argc<2) {
ohair@425 198 fprintf(stderr, "Usage: uncygdrive.exe /cygdrive/c/WINDOWS/notepad.exe /cygdrive/c/x/test.txt");
ohair@425 199 exit(0);
ohair@425 200 }
ohair@425 201
ohair@425 202 line = replace_cygdrive(strstr(GetCommandLine(), argv[1]));
ohair@425 203
ohair@425 204 for (i=1; i<argc; ++i) {
ohair@425 205 if (argv[i][0] == '@') {
ohair@425 206 // Found at-file! Fix it!
ohair@425 207 old_at_file = replace_cygdrive(argv[i]);
ohair@425 208 new_at_file = fix_at_file(old_at_file);
ohair@425 209 line = replace_substring(line, old_at_file, new_at_file);
ohair@425 210 }
ohair@425 211 }
ohair@425 212
ohair@425 213 if (getenv("DEBUG_UNCYGDRIVE") != NULL) {
ohair@425 214 fprintf(stderr, "uncygdrive >%s<\n", line);
ohair@425 215 }
ohair@425 216
ohair@425 217 ZeroMemory(&si,sizeof(si));
ohair@425 218 si.cb=sizeof(si);
ohair@425 219 ZeroMemory(&pi,sizeof(pi));
ohair@425 220
ohair@425 221 rc = CreateProcess(NULL,
ohair@425 222 line,
ohair@425 223 0,
ohair@425 224 0,
ohair@425 225 TRUE,
ohair@425 226 0,
ohair@425 227 0,
ohair@425 228 0,
ohair@425 229 &si,
ohair@425 230 &pi);
ohair@425 231 if(!rc)
ohair@425 232 {
ohair@425 233 //Could not start process;
ohair@425 234 fprintf(stderr, "Could not start process!\n");
ohair@425 235 exit(-1);
ohair@425 236 }
ohair@425 237
ohair@425 238 WaitForSingleObject(pi.hProcess,INFINITE);
ohair@425 239 GetExitCodeProcess(pi.hProcess,&exitCode);
ohair@425 240
ohair@425 241 if (getenv("DEBUG_UNCYGDRIVE") != NULL) {
ohair@425 242 for (i=0; i<num_files_to_delete; ++i) {
ohair@425 243 fprintf(stderr, "Not deleting temporary uncygdrive file %s\n",
ohair@425 244 files_to_delete[i]);
ohair@425 245 }
ohair@425 246 }
ohair@425 247 else {
ohair@425 248 for (i=0; i<num_files_to_delete; ++i) {
ohair@425 249 remove(files_to_delete[i]);
ohair@425 250 }
ohair@425 251 }
ohair@425 252
ohair@425 253 exit(exitCode);
ohair@425 254 }

mercurial