windows-build-updates-20030314
[openafs.git] / src / config / util_cr.c
1 /* crlf.c : Defines the entry point for the console application.*/
2
3 /* Copyright 2000, International Business Machines Corporation and others.
4         All Rights Reserved.
5  
6         This software has been released under the terms of the IBM Public
7         License.  For details, see the LICENSE file in the top-level source
8         directory or online at http://www.openafs.org/dl/license10.html
9
10 */
11
12 #undef _CRTDBG_MAP_ALLOC
13 #include "stdio.h"
14 #include "io.h"
15 #include <assert.h>
16 #include "string.h"
17 #include "process.h"
18 #include "windows.h"
19 #include "malloc.h"
20 #include "time.h"
21 #include "stdlib.h"
22 #include "windows.h"
23
24 #ifndef  intptr_t
25 #define intptr_t long
26 #endif
27
28 void usuage()
29 {
30         printf("util_cr file ;remove cr (from crlf)\n\
31         OR util_cr } ProductVersion in_filename out_filename ; substitute for %1-%5 in file\n\
32            %1=Major version, %2=Minor version, %3=Patch(first digit) %4=(last two digits) %5=Version display string \n\
33            ProductVersion=maj.min.pat.pat2 ;maj=numeric, min=numeric pat,pat2 are not more than 3 digits or 1-2 digits and one alpha \n\
34            e.g 1.0.4.1, 1.0.4 a 1.0.401, 1.0.4a  all represent the same version\n\
35         OR util_cr + file ;add cr\n \
36         OR util_cr * \"+[register key value] x=y\" ; add register key value\n\
37         OR util_cr * \"-[register key value]\" ; aremove register key value\n\
38         OR util_cr @ file.ini \"[SectionKey]variable=value\" ; update ini-ipr-pwf file\n\
39         OR util_cr @ file.ini \"[SectionKey]variable=value*DatE*\" ; update ini-ipr-pwf file, insert date\n\
40         OR util_cr ~  ;force error\n\
41         OR util_cr _del  [/q=quiet /s=recurese] [*. *. *.] ;delete \n\
42         OR util_cr _cpy [/q=quiet ] [*. *. *.] destinationFolder;\n\
43         OR util_cr _isOS [nt xp 98 9x w2] ;test for OS, return 1 if match else 0\n\
44         OR util_cr _dir !build type!source!object! set current directory in file->home base is used for offset\n\
45         OR unil_cr _ver return compiler version\n" );
46         exit(0xc000);
47 }
48
49 struct TRANSLATION {
50                 WORD langID;         // language ID
51                 WORD charset;        // character set (code page)
52 };
53
54 int CheckVersion(int argc,char *argv[])
55 {
56         OSVERSIONINFO VersionInfo;
57         int i;
58         memset(&VersionInfo,0,sizeof(VersionInfo));
59         VersionInfo.dwOSVersionInfoSize =sizeof(OSVERSIONINFO);
60         if (!GetVersionEx(&VersionInfo))
61         {
62                 return 0XC000;
63         }
64         for (i=2;i<argc;i++)
65         {
66                 if (stricmp(argv[i],"nt")==0)
67                 {
68                         if ((VersionInfo.dwPlatformId==VER_PLATFORM_WIN32_NT) 
69                                 && (VersionInfo.dwMajorVersion==4)
70                                 && (VersionInfo.dwMinorVersion==0))
71                                 return 1;
72                 }
73                 if (stricmp(argv[i],"xp")==0)
74                 {
75                         if ((VersionInfo.dwPlatformId==VER_PLATFORM_WIN32_NT) 
76                                 && (VersionInfo.dwMajorVersion==5)
77                                 && (VersionInfo.dwMinorVersion==1))
78                                 return 1;
79                 }
80                 if (stricmp(argv[i],"w2")==0)
81                 {
82                         if ((VersionInfo.dwPlatformId==VER_PLATFORM_WIN32_NT) 
83                                 && (VersionInfo.dwMajorVersion==5)
84                                 && (VersionInfo.dwMinorVersion==0))
85                                 return 1;
86                 }
87                 if (stricmp(argv[i],"98")==0)
88                 {
89                         if ((VersionInfo.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) && (VersionInfo.dwMinorVersion==10))
90                                 return 1;
91                 }
92                 if (stricmp(argv[i],"95")==0)
93                 {
94                         if ((VersionInfo.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) && (VersionInfo.dwMinorVersion==0))
95
96                                 return 1;
97                 }
98                 if (stricmp(argv[i],"9x")==0)
99                 {
100                         if (VersionInfo.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
101                                 return 1;
102                 }
103                 if (stricmp(argv[i],"_")==0)
104                         return 0;
105         }
106         return 0;
107 }
108
109 void Addkey (const char *hkey,const char *subkey,const char *stag,const char *sval)
110 {
111         DWORD disposition,result;
112         HKEY kPkey,kHkey=0;
113         if (strcmp(hkey,"HKEY_CLASSES_ROOT")==0) kHkey=HKEY_CLASSES_ROOT;
114         if (strcmp(hkey,"HKEY_CURRENT_USER")==0) kHkey=HKEY_CURRENT_USER;
115         if (strcmp(hkey,"HKEY_LOCAL_MACHINE")==0) kHkey=HKEY_LOCAL_MACHINE;
116         if (kHkey==0)
117                 usuage();
118         result=(RegCreateKeyEx(kHkey    /*HKEY_LOCAL_MACHINE*/
119                 ,subkey
120                 ,0,NULL
121                 ,REG_OPTION_NON_VOLATILE
122                 ,KEY_ALL_ACCESS,NULL
123                 ,&kPkey
124                 ,&disposition)==ERROR_SUCCESS);
125         if(!result)
126         {
127                 printf("AFS Error - Could Not create a registration key\n");
128                 exit(0xc000);
129         }
130         if (stag==NULL) return;
131         if ((sval)&&(strlen(sval)))
132         {
133                 if (*stag=='@')
134                         result=RegSetValueEx(kPkey,"",0,REG_SZ,(CONST BYTE *)sval,strlen(sval));
135                 else
136                         result=RegSetValueEx(kPkey,stag,0,REG_SZ,(CONST BYTE *)sval,strlen(sval));
137         } else {
138
139                 if (*stag=='@')
140                         result=(RegSetValueEx(kPkey,"",0,REG_SZ,(CONST BYTE *)"",0));
141                 else
142                         result=(RegSetValueEx(kPkey,stag,0,REG_SZ,(CONST BYTE *)"",0));
143         }
144         if(result!=ERROR_SUCCESS)
145         {
146                 printf("AFS Error - Could Not create a registration key\n");
147                 exit(0xc000);
148         }
149 }
150
151 void Subkey(const char *hkey,const char *subkey)
152 {
153         DWORD result;
154         HKEY kHkey=0;
155         if (strcmp(hkey,"HKEY_CLASSES_ROOT")==0) kHkey=HKEY_CLASSES_ROOT;
156         if (strcmp(hkey,"HKEY_CURRENT_USER")==0) kHkey=HKEY_CURRENT_USER;
157         if (strcmp(hkey,"HKEY_LOCAL_MACHINE")==0) kHkey=HKEY_LOCAL_MACHINE;
158         if (kHkey==0)
159                 usuage();
160         result=RegDeleteKey(
161                 kHkey,
162                 subkey
163         );
164         if(result!=ERROR_SUCCESS)
165         {
166                 printf("AFS Error - Could Not create a registration key\n");
167                 exit(0xc000);
168         }
169 }
170
171 void doremove(BOOL bRecurse,BOOL bQuiet,char* argv)
172 {
173         char *pParm;
174         char parm[MAX_PATH+1];
175         char basdir[MAX_PATH+1];
176         strcpy(parm,argv);
177         pParm=parm;
178         GetCurrentDirectory(sizeof(basdir),basdir);
179         if (strrchr(parm,'\\')!=NULL)
180         {/*jump to base directory*/
181                 pParm=strrchr(parm,'\\');
182                 *pParm=0;
183                 if (!SetCurrentDirectory(parm))
184                         return;
185                 pParm++;
186         }
187         if (!bRecurse)
188         {
189                 struct _finddata_t fileinfo;
190                 intptr_t hfile;
191                 BOOL bmore;
192                 char basdir[MAX_PATH+1];
193                 GetCurrentDirectory(sizeof(basdir),basdir);
194                 hfile=_findfirst(pParm,&fileinfo);
195                 bmore=(hfile!=-1);
196                 while (bmore)
197                 {
198                         if ((DeleteFile(fileinfo.name)==1) && (!bQuiet))
199                                 printf("Remove %s\\%s\n",basdir,fileinfo.name);
200                         bmore=(_findnext(hfile,&fileinfo)==0);
201                 }
202                 _findclose(hfile);
203         } else {
204         /*RECURSIVE LOOP - SCAN directories*/
205                 struct _finddata_t fileinfo;
206                 intptr_t hfile;
207                 BOOL bmore;
208                 doremove(FALSE,bQuiet,pParm);
209                 hfile=_findfirst("*.*",&fileinfo);
210                 bmore=(hfile!=-1);
211                 while (bmore)
212                 {
213                         if (fileinfo.attrib & _A_SUBDIR)
214                         {
215                                 if ((strcmp(fileinfo.name,".")!=0) && (strcmp(fileinfo.name,"..")!=0))
216                                 {
217                                         if (SetCurrentDirectory(fileinfo.name))
218                                                 doremove(TRUE,bQuiet,pParm);
219                                         SetCurrentDirectory(basdir);
220                                 }
221                         }
222                         bmore=(_findnext(hfile,&fileinfo)==0);
223                 }
224                 _findclose(hfile);
225         }
226         SetCurrentDirectory(basdir);
227 }
228
229 void gencurdir(char *val)
230 {
231         char bld[MAX_PATH+1],parm[MAX_PATH+1],src[MAX_PATH+1],obj[MAX_PATH+1],dir[MAX_PATH+1],curdir[MAX_PATH+1];
232         char *p,*po;
233         FILE *f;
234         BOOL isObjAbs,isSrcAbs; /* two flags to determine if either string is not relative*/
235         strcpy(bld,val+1);      /*it better be checked or free*/
236         strcpy(src,strchr(bld,'!')+1);
237         strcpy(obj,strchr(src,'!')+1);
238         *strchr(bld,'!')=0;
239         *strchr(obj,'!')=0;
240         *strchr(src,'!')=0;
241         isObjAbs=((*obj=='\\')||(strstr(obj,":")));
242         isSrcAbs=((*src=='\\')||(strstr(src,":")));
243         GetCurrentDirectory(MAX_PATH,dir);
244         strlwr(bld);
245         strlwr(dir);
246         strlwr(src);
247         strlwr(obj);
248         strcpy(curdir,dir);
249         strcat(curdir,"\\ \n");
250         if (GetTempPath(MAX_PATH,parm)==0)
251                 exit(0xc000);
252         strcat(parm,"home");
253         if ((f=fopen(parm,"w"))==NULL)
254                 exit(0xc000);
255         __try {
256         __try {
257                 if (obj[strlen(obj)-1]!='\\')
258                         strcat(obj,"\\");
259                 if (src[strlen(src)-1]!='\\')
260                         strcat(src,"\\");
261                 do {/* try to match src or obj*/
262                         if ((p=strstr(dir,src)) && isSrcAbs)
263                         {
264                                 po=p;
265                                 p+=strlen(src);
266                         } else if ((p=strstr(dir,src)) && !isSrcAbs && *(p-1)=='\\')
267                         {
268                                 po=p;
269                                 p+=strlen(src);
270                         } else if ( (p=strstr(dir,obj)) && isObjAbs)
271                         {
272                                 po=p;
273                                 p+=strlen(obj);
274                         } else if ((p=strstr(dir,obj)) && !isObjAbs && *(p-1)=='\\')
275                         {
276                                 po=p;
277                                 p+=strlen(obj);
278                         }
279                 } while (strstr(p,src)||strstr(p,obj));
280                 if (isObjAbs) {
281                         sprintf(parm,"OJT=%s%s\\%s \n",obj,bld,p);
282                 } else {
283                         *po=0;
284                         sprintf(parm,"OJT=%s%s%s\\%s \n",dir,obj,bld,p);
285                 }
286                 if (strcmp(curdir,parm+4)==0)   /* current directory is object*/
287                         strcpy(parm,"OJT= \n");
288                 fwrite(parm,strlen(parm),1,f);
289                 if (isSrcAbs) {
290                         sprintf(parm,"SRT=%s%s\\ \n",src,p);
291                 } else {
292                         *(p-strlen(src))=0;
293                         sprintf(parm,"SRT=%s%s%s\\ \n",dir,src,p);
294                 }
295                 if (strcmp(curdir,parm+4)==0)   /* current directory is object*/
296                         strcpy(parm,"SRT= \n");
297                 fwrite(parm,strlen(parm),1,f);
298                 /* now lets set the AFS_LASTCMP environment variable */
299                 sprintf(parm,"AFS_LASTCMP=%s\\%s",src,p);
300         }
301         __except(EXCEPTION_EXECUTE_HANDLER ){
302                 exit(0xc000);
303         }
304         }
305         __finally {
306                 fclose(f);
307         }   
308 }
309
310 int isequal(char *msg1,char *msg2,char *disp)
311 {
312         int x;
313         strlwr(msg1);
314         strlwr(msg2);
315         if (strcmp(msg1,msg2)!=0)
316                 return 0;
317         printf("ERROR -- %s \n",disp);
318         exit(0xc000);
319 }
320
321 int SetSysEnv(int argc,char * argv[])
322 {
323         long ret;
324         DWORD dwResult;
325         printf("assignment %s %s\n",argv[2],argv[3]);
326         Addkey("HKEY_LOCAL_MACHINE","System\\CurrentControlSet\\Control\\Session Manager\\Environment"
327                 ,argv[2]
328                 ,argv[3]
329                 );
330         SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE,0,(DWORD)"Environment",SMTO_NORMAL,1,&dwResult);
331         return 0;
332 }
333
334 int main(int argc, char* argv[])
335 {
336 /*      typedef char * CHARP;*/
337         char fname[128];
338         FILE *file;
339         int l,i;
340         char **pvar,*ch;
341         long len;
342         BOOL bRecurse=FALSE;
343         BOOL bQuiet=FALSE;
344         if (argc<2)
345                 usuage();
346         if (strcmp(argv[1],"_sysvar")==0)
347         {
348                 if (argc<4)
349                         usuage();
350                 return (SetSysEnv(argc,argv));
351
352         }
353         if (strnicmp(argv[1],"_dir",4)==0){ /*get current directory routine*/
354                 gencurdir(argv[1]);
355                 return 0;
356         }
357         if (strnicmp(argv[1],"_isequal",4)==0){ /*get current directory routine*/
358                 return isequal(argv[2],argv[3],argv[4]);
359         }
360         if (stricmp(argv[1],"_del")==0) /*DELETE routine*/
361         {
362                 int iargc=2;
363                 if ((argc>iargc) && (stricmp(argv[iargc],"/s")==0))
364                 {
365                         iargc++;
366                         bRecurse=TRUE;
367                 }
368                 if ((argc>iargc) && (stricmp(argv[iargc],"/q")==0))
369                 {
370                         iargc++;
371                         bQuiet=TRUE;
372                 }
373                 if ((argc>iargc) && (stricmp(argv[iargc],"/s")==0))
374                 {
375                         iargc++;
376                         bRecurse=TRUE;
377                 }
378                 while (iargc<argc)
379                 {
380                         doremove(bRecurse,bQuiet,argv[iargc]);
381                         iargc++;
382                 }
383                 return 0;
384         }
385         if (strcmp(argv[1],"_ver")==0)
386         {
387                 return _MSC_VER;
388         }
389          if (argc<3)
390                 usuage();
391         if (strcmp(argv[1],"_isOS")==0)
392                 return CheckVersion(argc,argv);
393         if (strcmp(argv[1],"}")==0)
394         {
395                 char v1[4],v2[4],v3[4],v4[4];
396                 char v5[132];
397                 char *ptr=NULL;
398                 char *buf;
399                 int maj;
400                 int min;
401                 int pat,pat2;
402                 strcpy(v5,argv[2]);
403                 if (argc<5)
404                         usuage();
405                 if ((ptr=strtok(argv[2],". \n"))==NULL)
406                         return 0;
407                 maj=atoi(ptr);
408                 if ((ptr=strtok(NULL,". \n"))==NULL)
409                         return 0;
410                 min=atoi(ptr);
411                 if ((ptr=strtok(NULL,". \n"))==NULL)
412                         return 0;
413                 pat2=-1;
414                 switch (strlen(ptr))
415                 {
416                 case 0:
417                         usuage();
418                 case 1:
419                         pat=atoi(ptr);
420                         if (isdigit(*ptr)!=0)
421                                 break;
422                         usuage();
423                 case 2: //ONLY 1.0.44 is interpreted as 1.0.4.4 or 1.0.4a as 1.0.4.a
424                         if (isdigit(*ptr)==0)
425                                 usuage();
426                         pat=*ptr-'0';
427                         ptr++;
428                         if (isalpha(*ptr)==0)
429                         {
430                                 pat2=atoi(ptr);
431                         } else if (isalpha(*ptr)!=0)
432                         {
433                                 pat2=tolower(*ptr)-'a'+1;
434                         } else 
435                                 usuage();
436                         break;                  
437                 case 3://1.0.401 or 1.0.40a are the same; 
438                         if ((isdigit(*ptr)==0)  // first 2 must be digit
439                                 || (isdigit(*(ptr+1)==0))
440                                 || (*(ptr+1)!='0' && isdigit(*(ptr+2))==0) // disallow 1.0.4b0  or 1.0.41a 
441                                 )
442                                 usuage();
443                         pat=*ptr-'0';
444                         ptr++;
445                         pat2=atoi(ptr);
446                         ptr++;
447                         if (isalpha(*ptr))
448                                 pat2=tolower(*ptr)-'a'+1;
449                         break;
450                 default:
451                         usuage();
452                 }
453                 // last can be 1-2 digits or one alpha (if pat2 hasn't been set)
454                 if ((ptr=strtok(NULL,". \n"))!=NULL)
455                 {
456                         if (pat2>=0)
457                                 usuage();
458                         switch (strlen(ptr))
459                         {
460                         case 1:
461                                 pat2=(isdigit(*ptr))?atoi(ptr):tolower(*ptr)-'a'+1;
462                                 break;
463                         case 2:
464                                 if ( 
465                                         isdigit(*ptr)==0 
466                                         || isdigit(*(ptr+1))==0
467                                         ) 
468                                         usuage();
469                                 pat2=atoi(ptr);
470                         default:
471                                 usuage();
472                         }
473                 }
474                 file=fopen(argv[3],"r");
475                 if (file==NULL)
476                         usuage();
477                 len=filelength(_fileno(file));
478                 buf=(char *)malloc(len+1);
479                 len=fread(buf,sizeof(char),len,file);
480                 buf[len]=0;     //set eof
481                 fclose(file);
482                 file=fopen(argv[4],"w");
483                 if (file==NULL)
484                         usuage();
485                 sprintf(v1,"%i",maj);
486                 sprintf(v2,"%i",min);
487                 sprintf(v3,"%i",pat);
488                 sprintf(v4,"%02i",pat2);
489                 while (1)
490                 {
491                         ptr=strstr(buf,"%");
492                         fwrite(buf,1,(ptr)?ptr-buf:strlen(buf),file);   //write file if no % found or up to %
493                         if (ptr==NULL)
494                                 break;
495                         switch (*(ptr+1))       //skip first scan if buf="1...."
496                         {
497                         case '1':
498                                 fwrite(v1,1,strlen(v1),file);
499                                 ptr++;
500                                 break;                          
501                         case '2':
502                                 fwrite(v2,1,strlen(v2),file);
503                                 ptr++;
504                                 break;                          
505                         case '3':
506                                 fwrite(v3,1,strlen(v3),file);
507                                 ptr++;
508                                 break;                          
509                         case '4':
510                                 fwrite(v4,1,strlen(v4),file);
511                                 ptr++;
512                                 break;                          
513                         case '5':
514                                 fwrite(v5,1,strlen(v5),file);
515                                 ptr++;
516                                 break;
517                         default:
518                                 fwrite("%",1,1,file);   //either % at end of file or no %1...
519                                 break;
520                         }
521                         buf=ptr+1;
522                 }
523                 fclose(file);
524                 return 0;
525         }
526         if (strcmp(argv[1],"~")==0)
527         {       //check for file presence
528                 if (fopen(argv[2],"r"))
529                         return(0);
530                 if(argc<4)
531                         printf("ERROR --- File not present %s\n",argv[2]);
532                 else 
533                         printf("Error---%s\n",argv[3]);
534                 exit(0xc000);
535         }
536         if (strcmp(argv[1],"*")==0)
537         {               /* "[HKEY_CLASSES_ROOT\CLSID\{DC515C27-6CAC-11D1-BAE7-00C04FD140D2}]  @=AFS Client Shell Extension" */
538                 if (argc<3)
539                         usuage();
540                 for (i=2;argc>=3;i++)
541                 {
542                         char *ssub=strtok(argv[i],"[");
543                         BOOL option;
544                         char *skey=strtok(NULL,"]");
545                         char *sval,*stag;
546                         if ((ssub==NULL) || (skey==NULL))
547                         {
548                                 printf("format error parameter %s\n",argv[i]);
549                                 exit(0xc000);
550                         }
551                         option=(*ssub=='-');
552                         stag=strtok(NULL,"\0");
553                         if (stag)
554                         while(*stag==' ') 
555                                 stag++;
556                         ssub=strtok(skey,"\\");
557                         ssub=strtok(NULL,"\0");
558                         sval=strtok(stag,"=");
559                         sval=strtok(NULL,"\0");
560                         switch (option)
561                         {
562                         case 0:
563                                 Addkey (skey,ssub,stag,sval);
564                                 break;
565                         default :
566                                 if (stag)
567                                         Addkey (skey,ssub,stag,"");
568                                 else
569                                         Subkey(skey,ssub);
570                                 break;
571                         }
572
573                         argc-=1;
574                 }
575                 return 0;
576         }
577         if (strcmp(argv[1],"@")==0)
578         {
579                 char msg[256],msgt[256];
580                 char *ptr;
581                 if (argc<4)
582                         usuage();
583                 for (i=3;argc>=4;i++)
584                 {
585
586                         char *ssect=strstr(argv[i],"[");
587                         char *skey=strstr(ssect,"]");
588                         char *sval;
589                         if ((ssect==NULL) || (skey==NULL))
590                         {
591                                 printf("format error parameter %s\n",argv[i]);
592                                 exit(0xc000);
593                         }
594                         ssect++;
595                         *skey=0;
596                         if ((strlen(skey+1)==0)||(strlen(ssect)==0))
597                         {
598                                 printf("format error parameter %s\n",argv[i]);
599                                 exit(0xc000);
600                         }
601                         while(*++skey==' ');
602                         sval=strstr(skey,"=");
603                         if (sval==NULL)
604                         {
605                                 printf("format error parameter %s\n",argv[i]);
606                                 exit(0xc000);
607                         }
608                         ptr=sval;
609                         while(*--ptr==' ') ;
610                         *(ptr+1)=0;
611                         while(*++sval==' ') ;
612                         if (ptr=strstr(sval,"*DatE*"))
613                         {// ok so lets substitute date in this string;
614                                 char tmpbuf[32];
615                                 *(ptr)=0;
616                                 strcpy(msg,sval);
617                             _tzset();
618                             _strdate( tmpbuf );
619                                 strcat(msg,tmpbuf);
620                                 strcat(msg,ptr+6);
621                                 sval=msg;
622                         }
623                         if (ptr=strstr(sval,"*TimE*"))
624                         {
625                                 char tmpbuf[32];
626                                 *(ptr)=0;
627                                 strcpy(msgt,sval);
628                             _strtime( tmpbuf );
629                                 strncat(msgt,tmpbuf,5);
630                                 strcat(msgt,ptr+6);
631                                 sval=msgt;
632                         }
633                         if (WritePrivateProfileString(ssect,skey,sval,argv[2])==0)
634                         {
635                                 LPVOID lpMsgBuf;
636                                 FormatMessage( 
637                                         FORMAT_MESSAGE_ALLOCATE_BUFFER | 
638                                         FORMAT_MESSAGE_FROM_SYSTEM | 
639                                         FORMAT_MESSAGE_IGNORE_INSERTS,
640                                         NULL,
641                                         GetLastError(),
642                                         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
643                                         (LPTSTR) &lpMsgBuf,
644                                         0,
645                                         NULL 
646                                 );
647                                 printf("Error writing profile string - %s",lpMsgBuf);
648                                 LocalFree( lpMsgBuf );
649                                 exit(0xc000);
650                         }
651                         argc-=1;
652                 }
653                 return 0;
654         }
655         strcpy(fname,argv[2]);
656         if (strcmp(argv[1],"+")==0)
657         {
658                 file=fopen(fname,"rb");
659                 if (file==NULL)
660                         exit(0xc000);
661                 len=filelength(_fileno(file));
662                 ch=(char *)malloc(len+2);
663                 *ch++=0;        /* a small hack to allow matching /r/n if /n is first character*/
664                 len=fread(ch,sizeof(char),len,file);
665                 file=freopen(fname,"wb",file);
666                 while (len-->0)
667                 {
668                         if ((*ch=='\n') && (*(ch-1)!='\r')) /*line feed alone*/
669                         {
670                                 fputc('\r',file);
671                         }
672                         fputc(*ch,file);
673                         ch++;
674                 }
675                 fclose(file);
676                 return 0;
677         }
678         if (strcmp(argv[1],"-")==0)
679         {
680                 strcpy(fname,argv[2]);
681                 file=fopen(fname,"rb");
682                 if (file==NULL)
683                         exit(0xc000);
684                 len=filelength(_fileno(file));
685                 ch=(char *)malloc(len+1);
686                 len=fread(ch,sizeof(char),len,file);
687                 file=freopen(fname,"wb",file);
688                 while (len-->0)
689                 {
690                         if (*ch!='\r')
691                                 fputc(*ch,file);
692                         ch++;
693                 }
694                 fclose(file);
695                 return 0;
696         }
697         if (strstr(fname,".et")==NULL)
698                 strcat(fname,".et");
699         file=fopen(fname,"rb");
700         if (file==NULL)
701                 exit(0xc000);
702         len=filelength(_fileno(file));
703         ch=(char *)malloc(len+1);
704         len=fread(ch,sizeof(char),len,file);
705         file=freopen(fname,"wb",file);
706         while (len-->0)
707         {
708                 if (*ch!='\r')
709                         fputc(*ch,file);
710                 ch++;
711         }
712         fclose(file);
713         pvar=(char **)malloc(argc*sizeof(char *));
714         for (i=1;i<argc-1;i++)
715                 pvar[i]=argv[i+1];
716         pvar[argc-1]=NULL;
717         pvar[0]=argv[1];
718         l=_spawnvp(_P_WAIT,argv[1],pvar);
719         if (ch)
720                 free(ch);
721         if (pvar)
722                 free(pvar);
723         return 0;
724 }