Index: src/add.c
==================================================================
--- src/add.c
+++ src/add.c
@@ -116,11 +116,11 @@
       "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)"
       "VALUES(%d,0,0,0,%Q,%d)",
       vid, zPath, file_isexe(zFullname));
     fossil_free(zFullname);
   }
-  printf("ADDED  %s\n", zPath);
+  fossil_print("ADDED  %s\n", zPath);
   return 1;
 }
 
 /*
 ** Add all files in the sfile temp table.
@@ -215,11 +215,11 @@
     isDir = file_isdir(zName);
     if( isDir==1 ){
       vfile_scan(&fullName, nRoot-1, includeDotFiles, pIgnore);
     }else if( isDir==0 ){
       fossil_fatal("not found: %s", zName);
-    }else if( access(zName, R_OK) ){
+    }else if( file_access(zName, R_OK) ){
       fossil_fatal("cannot open %s", zName);
     }else{
       char *zTreeName = &zName[nRoot];
       db_multi_exec(
          "INSERT OR IGNORE INTO sfile(x)"
@@ -280,11 +280,11 @@
     blob_reset(&treeName);
   }
   
   db_prepare(&loop, "SELECT x FROM sfile");
   while( db_step(&loop)==SQLITE_ROW ){
-    printf("DELETED %s\n", db_column_text(&loop, 0));
+    fossil_print("DELETED %s\n", db_column_text(&loop, 0));
   }
   db_finalize(&loop);
   db_multi_exec(
     "UPDATE vfile SET deleted=1 WHERE pathname IN sfile;"
     "DELETE FROM vfile WHERE rid=0 AND deleted;"
@@ -377,17 +377,17 @@
     zPath = db_column_text(&q, 1);
     if( !file_isfile(zPath) ){
       if( !isTest ){
         db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile);
       }
-      printf("DELETED  %s\n", zFile);
+      fossil_print("DELETED  %s\n", zFile);
       nDelete++;
     }
   }
   db_finalize(&q);
   /* show cmmand summary */
-  printf("added %d files, deleted %d files\n", nAdd, nDelete);
+  fossil_print("added %d files, deleted %d files\n", nAdd, nDelete);
 
   db_end_transaction(isTest);
 }
 
 
@@ -395,11 +395,11 @@
 ** Rename a single file.
 **
 ** The original name of the file is zOrig.  The new filename is zNew.
 */
 static void mv_one_file(int vid, const char *zOrig, const char *zNew){
-  printf("RENAME %s %s\n", zOrig, zNew);
+  fossil_print("RENAME %s %s\n", zOrig, zNew);
   db_multi_exec(
     "UPDATE vfile SET pathname='%s' WHERE pathname='%s' AND vid=%d",
     zNew, zOrig, vid
   );
 }

Index: src/allrepo.c
==================================================================
--- src/allrepo.c
+++ src/allrepo.c
@@ -129,22 +129,22 @@
      "  FROM global_config"
      " WHERE substr(name, 1, 5)=='repo:' ORDER BY 1"
   );
   while( db_step(&q)==SQLITE_ROW ){
     const char *zFilename = db_column_text(&q, 0);
-    if( access(zFilename, 0) ){
+    if( file_access(zFilename, 0) ){
       nMissing++;
       continue;
     }
     if( !file_is_canonical(zFilename) ) nMissing++;
     if( zCmd[0]=='l' ){
-      printf("%s\n", zFilename);
+      fossil_print("%s\n", zFilename);
       continue;
     }
     zQFilename = quoteFilename(zFilename);
     zSyscmd = mprintf("%s %s %s", zFossil, zCmd, zQFilename);
-    printf("%s\n", zSyscmd);
+    fossil_print("%s\n", zSyscmd);
     fflush(stdout);
     rc = fossil_system(zSyscmd);
     free(zSyscmd);
     free(zQFilename);
     if( stopOnError && rc ){
@@ -159,11 +159,11 @@
   if( nMissing ){
     db_begin_transaction();
     db_reset(&q);
     while( db_step(&q)==SQLITE_ROW ){
       const char *zFilename = db_column_text(&q, 0);
-      if( access(zFilename, 0) ){
+      if( file_access(zFilename, 0) ){
         char *zRepo = mprintf("repo:%s", zFilename);
         db_unset(zRepo, 1);
         free(zRepo);
       }else if( !file_is_canonical(zFilename) ){
         Blob cname;

Index: src/bisect.c
==================================================================
--- src/bisect.c
+++ src/bisect.c
@@ -184,11 +184,11 @@
   }else if( memcmp(zCmd, "options", n)==0 ){
     if( g.argc==3 ){
       unsigned int i;
       for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){
         char *z = mprintf("bisect-%s", aBisectOption[i].zName);
-        printf("  %-15s  %-6s  ", aBisectOption[i].zName,
+        fossil_print("  %-15s  %-6s  ", aBisectOption[i].zName,
                db_lget(z, (char*)aBisectOption[i].zDefault));
         fossil_free(z);
         comment_print(aBisectOption[i].zDesc, 27, 79);
       }
     }else if( g.argc==4 || g.argc==5 ){
@@ -198,11 +198,11 @@
         if( memcmp(g.argv[3], aBisectOption[i].zName, n)==0 ){
           char *z = mprintf("bisect-%s", aBisectOption[i].zName);
           if( g.argc==5 ){
             db_lset(z, g.argv[4]);
           }
-          printf("%s\n", db_lget(z, (char*)aBisectOption[i].zDefault));
+          fossil_print("%s\n", db_lget(z, (char*)aBisectOption[i].zDefault));
           fossil_free(z);
           break;
         }
       }
       if( i>=sizeof(aBisectOption)/sizeof(aBisectOption[0]) ){
@@ -230,19 +230,19 @@
     for(p=path_last(), n=0; p; p=p->pFrom, n++){
       const char *z;
       db_bind_int(&s, ":rid", p->rid);
       if( db_step(&s)==SQLITE_ROW ){
         z = db_column_text(&s, 0);
-        printf("%s", z);
-        if( p->rid==bisect.good ) printf(" GOOD");
-        if( p->rid==bisect.bad ) printf(" BAD");
-        if( p->rid==vid ) printf(" CURRENT");
-        if( nStep>1 && n==nStep/2 ) printf(" NEXT");
-        printf("\n");
+        fossil_print("%s", z);
+        if( p->rid==bisect.good ) fossil_print(" GOOD");
+        if( p->rid==bisect.bad ) fossil_print(" BAD");
+        if( p->rid==vid ) fossil_print(" CURRENT");
+        if( nStep>1 && n==nStep/2 ) fossil_print(" NEXT");
+        fossil_print("\n");
       }
       db_reset(&s);
     }
     db_finalize(&s);
   }else{
     usage("bad|good|next|reset|vlist ...");
   }
 }

Index: src/blob.c
==================================================================
--- src/blob.c
+++ src/blob.c
@@ -111,11 +111,11 @@
       assert( fossil_isspace((char)i) );
     }else{
       assert( !fossil_isspace((char)i) );
     }
   }
-  printf("All 256 characters OK\n");
+  fossil_print("All 256 characters OK\n");
 }
 
 /*
 ** This routine is called if a blob operation fails because we
 ** have run out of memory.
@@ -690,11 +690,11 @@
   }
   if( size==0 ){
     return 0;
   }
   blob_resize(pBlob, size);
-  in = fopen(zFilename, "rb");
+  in = fossil_fopen(zFilename, "rb");
   if( in==0 ){
     fossil_panic("cannot open %s for reading", zFilename);
   }
   got = fread(blob_buffer(pBlob), 1, size, in);
   fclose(in);
@@ -750,11 +750,11 @@
         }
 #endif
         zName[i] = '/';
       }
     }
-    out = fopen(zName, "wb");
+    out = fossil_fopen(zName, "wb");
     if( out==0 ){
       fossil_fatal_recursive("unable to open file \"%s\" for writing", zName);
       return 0;
     }
     needToClose = 1;
@@ -761,11 +761,11 @@
     if( zName!=zBuf ) free(zName);
   }
   blob_is_init(pBlob);
   wrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out);
   if( needToClose ) fclose(out);
-  if( wrote!=blob_size(pBlob) ){
+  if( wrote!=blob_size(pBlob) && out!=stdout ){
     fossil_fatal_recursive("short write: %d of %d bytes to %s", wrote,
        blob_size(pBlob), zFilename);
   }
   return wrote;
 }
@@ -925,11 +925,11 @@
     }
     blob_reset(&b1);
     blob_reset(&b2);
     blob_reset(&b3);
   }
-  printf("ok\n");
+  fossil_print("ok\n");
 }
 
 #if defined(_WIN32)
 /*
 ** Convert every \n character in the given blob into \r\n.

Index: src/branch.c
==================================================================
--- src/branch.c
+++ src/branch.c
@@ -157,13 +157,13 @@
     fossil_panic("unable to install new manifest");
   }
   assert( blob_is_reset(&branch) );
   content_deltify(rootid, brid, 0);
   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
-  printf("New branch: %s\n", zUuid);
+  fossil_print("New branch: %s\n", zUuid);
   if( g.argc==3 ){
-    printf(
+    fossil_print(
       "\n"
       "Note: the local check-out has not been updated to the new\n"
       "      branch.  To begin working on the new branch, do this:\n"
       "\n"
       "      %s update %s\n",
@@ -229,11 +229,11 @@
       TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
     );
     while( db_step(&q)==SQLITE_ROW ){
       const char *zBr = db_column_text(&q, 0);
       int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0;
-      printf("%s%s\n", (isCur ? "* " : "  "), zBr);
+      fossil_print("%s%s\n", (isCur ? "* " : "  "), zBr);
     }
     db_finalize(&q);
   }else{
     fossil_panic("branch subcommand should be one of: "
                  "new list ls");

Index: src/captcha.c
==================================================================
--- src/captcha.c
+++ src/captcha.c
@@ -392,11 +392,11 @@
   for(i=2; i<g.argc; i++){
     char zHex[30];
     v = (unsigned int)atoi(g.argv[i]);
     sqlite3_snprintf(sizeof(zHex), zHex, "%x", v);
     z = captcha_render(zHex);
-    printf("%s:\n%s", zHex, z);
+    fossil_print("%s:\n%s", zHex, z);
     free(z);
   }
 }
 
 /*

Index: src/cgi.c
==================================================================
--- src/cgi.c
+++ src/cgi.c
@@ -2,11 +2,11 @@
 ** Copyright (c) 2006 D. Richard Hipp
 **
 ** This program is free software; you can redistribute it and/or
 ** modify it under the terms of the Simplified BSD License (also
 ** known as the "2-Clause License" or "FreeBSD License".)
-
+**
 ** This program is distributed in the hope that it will be useful,
 ** but without any warranty; without even the implied warranty of
 ** merchantability or fitness for a particular purpose.
 **
 ** Author contact information:
@@ -1116,11 +1116,11 @@
     }
   }
   if( iPort>mxPort ) return 1;
   listen(listener,10);
   if( iPort>mnPort ){
-    printf("Listening for HTTP requests on TCP port %d\n", iPort);
+    fossil_print("Listening for HTTP requests on TCP port %d\n", iPort);
     fflush(stdout);
   }
   if( zBrowser ){
     zBrowser = mprintf(zBrowser, iPort);
     system(zBrowser);

Index: src/checkin.c
==================================================================
--- src/checkin.c
+++ src/checkin.c
@@ -54,11 +54,11 @@
     char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
     blob_append(report, zPrefix, nPrefix);
     if( isDeleted ){
       blob_appendf(report, "DELETED    %s\n", zPathname);
     }else if( !file_isfile(zFullName) ){
-      if( access(zFullName, 0)==0 ){
+      if( file_access(zFullName, 0)==0 ){
         blob_appendf(report, "NOT_A_FILE %s\n", zPathname);
         if( missingIsFatal ){
           fossil_warning("not a file: %s", zPathname);
           nErr++;
         }
@@ -136,13 +136,13 @@
 */
 void status_cmd(void){
   int vid;
   db_must_be_within_tree();
        /* 012345678901234 */
-  printf("repository:   %s\n", db_lget("repository",""));
-  printf("local-root:   %s\n", g.zLocalRoot);
-  printf("server-code:  %s\n", db_get("server-code", ""));
+  fossil_print("repository:   %s\n", db_lget("repository",""));
+  fossil_print("local-root:   %s\n", g.zLocalRoot);
+  fossil_print("server-code:  %s\n", db_get("server-code", ""));
   vid = db_lget_int("checkout", 0);
   if( vid ){
     show_common_info(vid, "checkout:", 1, 1);
   }
   changes_cmd();
@@ -176,27 +176,27 @@
     int isNew = db_column_int(&q,2)==0;
     int chnged = db_column_int(&q,3);
     int renamed = db_column_int(&q,4);
     char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
     if( isBrief ){
-      printf("%s\n", zPathname);
+      fossil_print("%s\n", zPathname);
     }else if( isNew ){
-      printf("ADDED      %s\n", zPathname);
+      fossil_print("ADDED      %s\n", zPathname);
     }else if( isDeleted ){
-      printf("DELETED    %s\n", zPathname);
+      fossil_print("DELETED    %s\n", zPathname);
     }else if( !file_isfile(zFullName) ){
-      if( access(zFullName, 0)==0 ){
-        printf("NOT_A_FILE %s\n", zPathname);
+      if( file_access(zFullName, 0)==0 ){
+        fossil_print("NOT_A_FILE %s\n", zPathname);
       }else{
-        printf("MISSING    %s\n", zPathname);
+        fossil_print("MISSING    %s\n", zPathname);
       }
     }else if( chnged ){
-      printf("EDITED     %s\n", zPathname);
+      fossil_print("EDITED     %s\n", zPathname);
     }else if( renamed ){
-      printf("RENAMED    %s\n", zPathname);
+      fossil_print("RENAMED    %s\n", zPathname);
     }else{
-      printf("UNCHANGED  %s\n", zPathname);
+      fossil_print("UNCHANGED  %s\n", zPathname);
     }
     free(zFullName);
   }
   db_finalize(&q);
 }
@@ -244,11 +244,11 @@
   );
   if( file_tree_name(g.zRepositoryName, &repo, 0) ){
     db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
   }
   while( db_step(&q)==SQLITE_ROW ){
-    printf("%s\n", db_column_text(&q, 0));
+    fossil_print("%s\n", db_column_text(&q, 0));
   }
   db_finalize(&q);
 }
 
 /*
@@ -302,19 +302,19 @@
   if( file_tree_name(g.zRepositoryName, &repo, 0) ){
     db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
   }
   while( db_step(&q)==SQLITE_ROW ){
     if( allFlag ){
-      unlink(db_column_text(&q, 0));
+      file_delete(db_column_text(&q, 0));
     }else{
       Blob ans;
       char *prompt = mprintf("remove unmanaged file \"%s\" (y/N)? ",
                               db_column_text(&q, 0));
       blob_zero(&ans);
       prompt_user(prompt, &ans);
       if( blob_str(&ans)[0]=='y' ){
-        unlink(db_column_text(&q, 0));
+        file_delete(db_column_text(&q, 0));
       }
     }
   }
   db_finalize(&q);
 }
@@ -395,26 +395,31 @@
   blob_add_cr(&text);
 #endif
   blob_write_to_file(&text, zFile);
   if( zEditor ){
     zCmd = mprintf("%s \"%s\"", zEditor, zFile);
-    printf("%s\n", zCmd);
+    fossil_print("%s\n", zCmd);
     if( fossil_system(zCmd) ){
       fossil_panic("editor aborted");
     }
     blob_reset(&text);
     blob_read_from_file(&text, zFile);
   }else{
     char zIn[300];
     blob_reset(&text);
     while( fgets(zIn, sizeof(zIn), stdin)!=0 ){
-      if( zIn[0]=='.' && (zIn[1]==0 || zIn[1]=='\r' || zIn[1]=='\n') ) break;
+      char *zUtf8 = fossil_mbcs_to_utf8(zIn);
+      if( zUtf8[0]=='.' && (zUtf8[1]==0 || zUtf8[1]=='\r' || zUtf8[1]=='\n') ){
+        fossil_mbcs_free(zUtf8);
+        break;
+      }
       blob_append(&text, zIn, -1);
+      fossil_mbcs_free(zUtf8);
     }
   }
   blob_remove_cr(&text);
-  unlink(zFile);
+  file_delete(zFile);
   free(zFile);
   blob_zero(pComment);
   while( blob_line(&text, &line) ){
     int i, n;
     char *z;
@@ -1084,11 +1089,11 @@
   db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
   manifest_crosslink(nvid, &manifest);
   assert( blob_is_reset(&manifest) );
   content_deltify(vid, nvid, 0);
   zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
-  printf("New_Version: %s\n", zUuid);
+  fossil_print("New_Version: %s\n", zUuid);
   if( outputManifest ){
     zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
     blob_zero(&muuid);
     blob_appendf(&muuid, "%s\n", zUuid);
     blob_write_to_file(&muuid, zManifestFile);
@@ -1153,8 +1158,8 @@
 
   if( !g.markPrivate ){
     autosync(AUTOSYNC_PUSH);  
   }
   if( count_nonbranch_children(vid)>1 ){
-    printf("**** warning: a fork has occurred *****\n");
+    fossil_print("**** warning: a fork has occurred *****\n");
   }
 }

Index: src/checkout.c
==================================================================
--- src/checkout.c
+++ src/checkout.c
@@ -157,16 +157,16 @@
     free(zManFile);
     blob_reset(&hash);
   }else{
     if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){
       zManFile = mprintf("%smanifest", g.zLocalRoot);
-      unlink(zManFile);
+      file_delete(zManFile);
       free(zManFile);
     }
     if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
       zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
-      unlink(zManFile);
+      file_delete(zManFile);
       free(zManFile);
     }
   }
     
 }
@@ -249,14 +249,14 @@
   db_multi_exec("DELETE FROM vmerge");
   if( !keepFlag && db_get_boolean("repo-cksum",1) ){
     vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b);
     vfile_aggregate_checksum_disk(vid, &cksum2);
     if( blob_compare(&cksum1, &cksum2) ){
-      printf("WARNING: manifest checksum does not agree with disk\n");
+      fossil_print("WARNING: manifest checksum does not agree with disk\n");
     }
     if( blob_size(&cksum1b) && blob_compare(&cksum1, &cksum1b) ){
-      printf("WARNING: manifest checksum does not agree with manifest\n");
+      fossil_print("WARNING: manifest checksum does not agree with manifest\n");
     }
   }
   db_end_transaction(0);
 }
 
@@ -268,11 +268,11 @@
   int i;
   for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){
     if( manifestOnly==0 || zReserved[0]=='m' ){
       char *z;
       z = mprintf("%s%s", g.zLocalRoot, zReserved);
-      unlink(z);
+      file_delete(z);
       free(z);
     }
   }
 }
 

Index: src/clearsign.c
==================================================================
--- src/clearsign.c
+++ src/clearsign.c
@@ -52,11 +52,11 @@
   }else{
     if( pOut!=pIn ){
       blob_copy(pOut, pIn);
     }
   }
-  unlink(zOut);
-  unlink(zIn);
+  file_delete(zOut);
+  file_delete(zIn);
   free(zOut);
   free(zIn);
   return rc;
 }

Index: src/clone.c
==================================================================
--- src/clone.c
+++ src/clone.c
@@ -80,11 +80,11 @@
     shun_artifacts();
     g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'");
     if( g.zLogin==0 ){
       db_create_default_users(1,zDefaultUser);
     }
-    printf("Repository cloned into %s\n", g.argv[3]);
+    fossil_print("Repository cloned into %s\n", g.argv[3]);
   }else{
     db_create_repository(g.argv[3]);
     db_open_repository(g.argv[3]);
     db_begin_transaction();
     db_record_repository_filename(g.argv[3]);
@@ -104,19 +104,19 @@
     g.xlinkClusterOnly = 0;
     verify_cancel();
     db_end_transaction(0);
     db_close(1);
     if( nErr ){
-      unlink(g.argv[3]);
+      file_delete(g.argv[3]);
       fossil_fatal("server returned an error - clone aborted");
     }
     db_open_repository(g.argv[3]);
   }
   db_begin_transaction();
-  printf("Rebuilding repository meta-data...\n");
+  fossil_print("Rebuilding repository meta-data...\n");
   rebuild_db(0, 1, 0);
-  printf("project-id: %s\n", db_get("project-code", 0));
-  printf("server-id:  %s\n", db_get("server-code", 0));
+  fossil_print("project-id: %s\n", db_get("project-code", 0));
+  fossil_print("server-id:  %s\n", db_get("server-code", 0));
   zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
-  printf("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
+  fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
   db_end_transaction(0);
 }

Index: src/comformat.c
==================================================================
--- src/comformat.c
+++ src/comformat.c
@@ -41,11 +41,11 @@
 
   for(;;){
     while( fossil_isspace(zText[0]) ){ zText++; }
     if( zText[0]==0 ){
       if( doIndent==0 ){
-        printf("\n");
+        fossil_print("\n");
         lineCnt = 1;
       }
       return lineCnt;
     }
     for(sk=si=i=k=0; zText[i] && k<tlen; i++){
@@ -64,23 +64,23 @@
         }
         k++;
       }
     }
     if( doIndent ){
-      printf("%*s", indent, "");
+      fossil_print("%*s", indent, "");
     }
     doIndent = 1;
     if( sk>0 && zText[i] ){
       zText += si;
       zBuf[sk++] =  '\n';
       zBuf[sk] = 0;
-      printf("%s", zBuf);
+      fossil_print("%s", zBuf);
     }else{
       zText += i;
       zBuf[k++] =  '\n';
       zBuf[k] = 0;
-      printf("%s", zBuf);
+      fossil_print("%s", zBuf);
     }
     lineCnt++;
   }
 }
 
@@ -93,8 +93,8 @@
   int indent;
   if( g.argc!=4 ){
     usage("PREFIX TEXT");
   }
   indent = strlen(g.argv[2]) + 1;
-  printf("%s ", g.argv[2]);
-  printf("(%d lines output)\n", comment_print(g.argv[3], indent, 79));
+  fossil_print("%s ", g.argv[2]);
+  fossil_print("(%d lines output)\n", comment_print(g.argv[3], indent, 79));
 }

Index: src/configure.c
==================================================================
--- src/configure.c
+++ src/configure.c
@@ -688,13 +688,13 @@
     if( strncmp(z, &aGroupName[i].zName[1], n)==0 ){
       return aGroupName[i].groupMask;
     }
   }
   if( notFoundIsFatal ){
-    printf("Available configuration areas:\n");
+    fossil_print("Available configuration areas:\n");
     for(i=0; i<count(aGroupName); i++){
-      printf("  %-10s %s\n", &aGroupName[i].zName[1], aGroupName[i].zHelp);
+      fossil_print("  %-10s %s\n", &aGroupName[i].zName[1], aGroupName[i].zHelp);
     }
     fossil_fatal("no such configuration area: \"%s\"", z);
   }
   return 0;
 }
@@ -883,14 +883,14 @@
       }else if( fossil_strcmp(zName,"@reportfmt")==0 ){
         db_multi_exec("DELETE FROM reportfmt");
       }
     }
     db_end_transaction(0);
-    printf("Configuration reset to factory defaults.\n");
-    printf("To recover, use:  %s %s import %s\n", 
+    fossil_print("Configuration reset to factory defaults.\n");
+    fossil_print("To recover, use:  %s %s import %s\n", 
             fossil_nameofexe(), g.argv[1], zBackup);
   }else
   {
     fossil_fatal("METHOD should be one of:"
                  " export import merge pull push reset");
   }
 }

Index: src/content.c
==================================================================
--- src/content.c
+++ src/content.c
@@ -670,11 +670,11 @@
   if( g.argc!=3 ) usage("FILENAME");
   db_must_be_within_tree();
   user_select();
   blob_read_from_file(&content, g.argv[2]);
   rid = content_put(&content);
-  printf("inserted as record %d\n", rid);
+  fossil_print("inserted as record %d\n", rid);
 }
 
 /*
 ** Make sure the content at rid is the original content and is not a
 ** delta.
@@ -838,14 +838,14 @@
   while( db_step(&q)==SQLITE_ROW ){
     int rid = db_column_int(&q, 0);
     const char *zUuid = db_column_text(&q, 1);
     int size = db_column_int(&q, 2);
     n1++;
-    printf("  %d/%d\r", n1, total);
+    fossil_print("  %d/%d\r", n1, total);
     fflush(stdout);
     if( size<0 ){
-      printf("skip phantom %d %s\n", rid, zUuid);
+      fossil_print("skip phantom %d %s\n", rid, zUuid);
       continue;  /* Ignore phantoms */
     }
     content_get(rid, &content);
     if( blob_size(&content)!=size ){
       fossil_warning("size mismatch on blob rid=%d:  %d vs %d",
@@ -859,7 +859,7 @@
     blob_reset(&cksum);
     blob_reset(&content);
     n2++;
   }
   db_finalize(&q);
-  printf("%d non-phantom blobs (out of %d total) verified\n", n2, n1);
+  fossil_print("%d non-phantom blobs (out of %d total) verified\n", n2, n1);
 }

Index: src/db.c
==================================================================
--- src/db.c
+++ src/db.c
@@ -166,11 +166,11 @@
     nBegin = 0;
   }
   busy = 0;
   db_close(0);
   for(i=0; i<nDeleteOnFail; i++){
-    unlink(azDeleteOnFail[i]);
+    file_delete(azDeleteOnFail[i]);
   }
 }
 
 /*
 ** Install a commit hook.  Hooks are installed in sequence order.
@@ -695,10 +695,11 @@
   if( zHome==0 ){
     fossil_fatal("cannot locate home directory - "
                 "please set the LOCALAPPDATA or APPDATA or HOMEPATH "
                 "environment variables");
   }
+  zHome = fossil_mbcs_to_utf8(zHome);
 #else
   zHome = getenv("HOME");
   if( zHome==0 ){
     fossil_fatal("cannot locate home directory - "
                  "please set the HOME environment variable");
@@ -740,11 +741,11 @@
 static int isValidLocalDb(const char *zDbName){
   i64 lsize;
   int rc;
   sqlite3_stmt *pStmt;
 
-  if( access(zDbName, F_OK) ) return 0;
+  if( file_access(zDbName, F_OK) ) return 0;
   lsize = file_size(zDbName);
   if( lsize%1024!=0 || lsize<4096 ) return 0;
   db_open_or_attach(zDbName, "localdb");
   g.localOpen = 1;
   db_open_config(0);
@@ -815,11 +816,11 @@
   n = strlen(zPwd);
   zPwdConv = mprintf("%/", zPwd);
   strncpy(zPwd, zPwdConv, 2000-20);
   free(zPwdConv);
   while( n>0 ){
-    if( access(zPwd, W_OK) ) break;
+    if( file_access(zPwd, W_OK) ) break;
     for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){
       sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]);
       if( isValidLocalDb(zPwd) ){
         /* Found a valid checkout database file */
         zPwd[n] = 0;
@@ -853,15 +854,15 @@
     }
     if( zDbName==0 ){
       db_err("unable to find the name of a repository database");
     }
   }
-  if( access(zDbName, R_OK) || file_size(zDbName)<1024 ){
-    if( access(zDbName, 0) ){
+  if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){
+    if( file_access(zDbName, 0) ){
       fossil_panic("repository does not exist or"
                    " is in an unreadable directory: %s", zDbName);
-    }else if( access(zDbName, R_OK) ){
+    }else if( file_access(zDbName, R_OK) ){
       fossil_panic("read permission denied for repository %s", zDbName);
     }else{
       fossil_panic("not a valid repository: %s", zDbName);
     }
   }
@@ -964,11 +965,11 @@
     fossil_fatal("not in a local checkout");
     return;
   }
   file_canonical_name(g.argv[2], &repo);
   zRepo = blob_str(&repo);
-  if( access(zRepo, 0) ){
+  if( file_access(zRepo, 0) ){
     fossil_fatal("no such file: %s", zRepo);
   }
   db_open_or_attach(zRepo, "test_repo");
   db_lset("repository", blob_str(&repo));
   db_close(1);

Index: src/deltacmd.c
==================================================================
--- src/deltacmd.c
+++ src/deltacmd.c
@@ -52,21 +52,18 @@
   Blob orig, target, delta;
   if( g.argc!=5 ){
     usage("ORIGIN TARGET DELTA");
   }
   if( blob_read_from_file(&orig, g.argv[2])<0 ){
-    fprintf(stderr,"cannot read %s\n", g.argv[2]);
-    fossil_exit(1);
+    fossil_fatal("cannot read %s\n", g.argv[2]);
   }
   if( blob_read_from_file(&target, g.argv[3])<0 ){
-    fprintf(stderr,"cannot read %s\n", g.argv[3]);
-    fossil_exit(1);
+    fossil_fatal("cannot read %s\n", g.argv[3]);
   }
   blob_delta_create(&orig, &target, &delta);
   if( blob_write_to_file(&delta, g.argv[4])<blob_size(&delta) ){
-    fprintf(stderr,"cannot write %s\n", g.argv[4]);
-    fossil_exit(1);
+    fossil_fatal("cannot write %s\n", g.argv[4]);
   }
   blob_reset(&orig);
   blob_reset(&target);
   blob_reset(&delta);
 }
@@ -114,21 +111,18 @@
   Blob orig, target, delta;
   if( g.argc!=5 ){
     usage("ORIGIN DELTA TARGET");
   }
   if( blob_read_from_file(&orig, g.argv[2])<0 ){
-    fprintf(stderr,"cannot read %s\n", g.argv[2]);
-    fossil_exit(1);
+    fossil_fatal("cannot read %s\n", g.argv[2]);
   }
   if( blob_read_from_file(&delta, g.argv[3])<0 ){
-    fprintf(stderr,"cannot read %s\n", g.argv[3]);
-    fossil_exit(1);
+    fossil_fatal("cannot read %s\n", g.argv[3]);
   }
   blob_delta_apply(&orig, &delta, &target);
   if( blob_write_to_file(&target, g.argv[4])<blob_size(&target) ){
-    fprintf(stderr,"cannot write %s\n", g.argv[4]);
-    fossil_exit(1);
+    fossil_fatal("cannot write %s\n", g.argv[4]);
   }
   blob_reset(&orig);
   blob_reset(&target);
   blob_reset(&delta);
 }
@@ -152,7 +146,7 @@
   blob_delta_apply(&f1, &d12, &a2);
   blob_delta_apply(&f2, &d21, &a1);
   if( blob_compare(&f1,&a1) || blob_compare(&f2, &a2) ){
     fossil_panic("delta test failed");
   }
-  printf("ok\n");
+  fossil_print("ok\n");
 }

Index: src/diff.c
==================================================================
--- src/diff.c
+++ src/diff.c
@@ -590,15 +590,15 @@
   int i;
   int *R;
   if( g.argc<4 ) usage("FILE1 FILE2 ...");
   blob_read_from_file(&a, g.argv[2]);
   for(i=3; i<g.argc; i++){
-    if( i>3 ) printf("-------------------------------\n");
+    if( i>3 ) fossil_print("-------------------------------\n");
     blob_read_from_file(&b, g.argv[i]);
     R = text_diff(&a, &b, 0, 0, 0);
     for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){
-      printf(" copy %4d  delete %4d  insert %4d\n", R[r], R[r+1], R[r+2]);
+      fossil_print(" copy %4d  delete %4d  insert %4d\n", R[r], R[r+1], R[r+2]);
     }
     /* free(R); */
     blob_reset(&b);
   }
 }
@@ -743,11 +743,11 @@
     }
   }
   for(i=0; i<x.nOrig; i++){
     const char *zSrc = x.aOrig[i].zSrc;
     if( zSrc==0 ) zSrc = g.argv[g.argc-1];
-    printf("%10s: %.*s\n", zSrc, x.aOrig[i].n, x.aOrig[i].z);
+    fossil_print("%10s: %.*s\n", zSrc, x.aOrig[i].n, x.aOrig[i].z);
   }
 }
 
 /* Annotation flags */
 #define ANN_FILE_VERS  0x001  /* Show file version rather than commit version */
@@ -926,8 +926,9 @@
       printf("version %3d: %s\n", i+1, ann.azVers[i]);
     }
     printf("---------------------------------------------------\n");
   }
   for(i=0; i<ann.nOrig; i++){
-    printf("%s: %.*s\n", ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
+    fossil_print("%s: %.*s\n", 
+                 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
   }
 }

Index: src/diffcmd.c
==================================================================
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -100,11 +100,11 @@
     ** zFile2 */
     blob_zero(&nameFile1);
     do{
       blob_reset(&nameFile1);
       blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++);
-    }while( access(blob_str(&nameFile1),0)==0 );
+    }while( file_access(blob_str(&nameFile1),0)==0 );
     blob_write_to_file(pFile1, blob_str(&nameFile1));
 
     /* Construct the external diff command */
     blob_zero(&cmd);
     blob_appendf(&cmd, "%s ", zDiffCmd);
@@ -114,11 +114,11 @@
 
     /* Run the external diff command */
     fossil_system(blob_str(&cmd));
 
     /* Delete the temporary file and clean up memory used */
-    unlink(blob_str(&nameFile1));
+    file_delete(blob_str(&nameFile1));
     blob_reset(&nameFile1);
     blob_reset(&cmd);
   }
 }
 
@@ -168,12 +168,12 @@
 
     /* Run the external diff command */
     fossil_system(blob_str(&cmd));
 
     /* Delete the temporary file and clean up memory used */
-    unlink(zTemp1);
-    unlink(zTemp2);
+    file_delete(zTemp1);
+    file_delete(zTemp2);
     blob_reset(&cmd);
   }
 }
 
 /*
@@ -263,11 +263,11 @@
     char *zToFree = zFullName;
     int showDiff = 1;
     if( isDeleted ){
       diff_printf("DELETED  %s\n", zPathname);
       if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; }
-    }else if( access(zFullName, 0) ){
+    }else if( file_access(zFullName, 0) ){
       diff_printf("MISSING  %s\n", zPathname);
       if( !asNewFile ){ showDiff = 0; }
     }else if( isNew ){
       diff_printf("ADDED    %s\n", zPathname);
       srcid = 0;

Index: src/encode.c
==================================================================
--- src/encode.c
+++ src/encode.c
@@ -340,11 +340,11 @@
 void test_encode64_cmd(void){
   char *z;
   int i;
   for(i=2; i<g.argc; i++){
     z = encode64(g.argv[i], -1);
-    printf("%s\n", z);
+    fossil_print("%s\n", z);
     free(z);
   }
 }
 
 
@@ -405,11 +405,11 @@
 void test_decode64_cmd(void){
   char *z;
   int i, n;
   for(i=2; i<g.argc; i++){
     z = decode64(g.argv[i], &n);
-    printf("%d: %s\n", n, z);
+    fossil_print("%d: %s\n", n, z);
     free(z);
   }
 }
 
 /*
@@ -579,13 +579,13 @@
   int i;
   char *z, *z2;
   for(i=2; i<g.argc; i++){
     z = obscure(g.argv[i]);
     z2 = unobscure(z);
-    printf("OBSCURE:    %s -> %s (%s)\n", g.argv[i], z, z2);
+    fossil_print("OBSCURE:    %s -> %s (%s)\n", g.argv[i], z, z2);
     free(z);
     free(z2);
     z = unobscure(g.argv[i]);
-    printf("UNOBSCURE:  %s -> %s\n", g.argv[i], z);
+    fossil_print("UNOBSCURE:  %s -> %s\n", g.argv[i], z);
     free(z);
   }
 }

Index: src/file.c
==================================================================
--- src/file.c
+++ src/file.c
@@ -47,17 +47,19 @@
 static int getStat(const char *zFilename){
   int rc = 0;
   if( zFilename==0 ){
     if( fileStatValid==0 ) rc = 1;
   }else{
-    if( stat(zFilename, &fileStat)!=0 ){
+    char *zMbcs = fossil_utf8_to_mbcs(zFilename);
+    if( stat(zMbcs, &fileStat)!=0 ){
       fileStatValid = 0;
       rc = 1;
     }else{
       fileStatValid = 1;
       rc = 0;
     }
+    fossil_mbcs_free(zMbcs);
   }
   return rc;
 }
 
 
@@ -120,10 +122,20 @@
   }else{
     rc = getStat(0);
   }
   return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
 }
+
+/*
+** Wrapper around the access() system call.
+*/
+int file_access(const char *zFilename, int flags){
+  char *zMbcs = fossil_utf8_to_mbcs(zFilename);
+  int rc = access(zMbcs, flags);
+  fossil_mbcs_free(zMbcs);
+  return rc;
+}
 
 /*
 ** Find an unused filename similar to zBase with zSuffix appended.
 **
 ** Make the name relative to the working directory if relFlag is true.
@@ -166,13 +178,13 @@
 */
 void file_copy(const char *zFrom, const char *zTo){
   FILE *in, *out;
   int got;
   char zBuf[8192];
-  in = fopen(zFrom, "rb");
+  in = fossil_fopen(zFrom, "rb");
   if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom);
-  out = fopen(zTo, "wb");
+  out = fossil_fopen(zTo, "wb");
   if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo);
   while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){
     fwrite(zBuf, 1, got, out);
   }
   fclose(in);
@@ -200,10 +212,19 @@
     }
   }
 #endif /* _WIN32 */
   return rc;
 }
+
+/*
+** Delete a file.
+*/
+void file_delete(const char *zFilename){
+  char *z = fossil_utf8_to_mbcs(zFilename);
+  unlink(z);
+  fossil_mbcs_free(z);
+}
 
 /*
 ** Create the directory named in the argument, if it does not already
 ** exist.  If forceFlag is 1, delete any prior non-directory object 
 ** with the same name.
@@ -212,15 +233,19 @@
 */
 int file_mkdir(const char *zName, int forceFlag){
   int rc = file_isdir(zName);
   if( rc==2 ){
     if( !forceFlag ) return 1;
-    unlink(zName);
+    file_delete(zName);
   }
   if( rc!=1 ){
 #if defined(_WIN32)
-    return mkdir(zName);
+    int rc;
+    char *zMbcs = fossil_utf8_to_mbcs(zName);
+    rc = mkdir(zMbcs);
+    fossil_mbcs_free(zMbcs);
+    return rc;
 #else
     return mkdir(zName, 0755);
 #endif
   }
   return 0;
@@ -350,13 +375,13 @@
 void cmd_test_simplify_name(void){
   int i;
   char *z;
   for(i=2; i<g.argc; i++){
     z = mprintf("%s", g.argv[i]);
-    printf("[%s] -> ", z);
+    fossil_print("[%s] -> ", z);
     file_simplify_name(z, -1);
-    printf("[%s]\n", z);
+    fossil_print("[%s]\n", z);
     fossil_free(z);
   }
 }
 
 /*
@@ -377,12 +402,11 @@
     blob_set(pOut, zOrigName);
     blob_materialize(pOut);
   }else{
     char zPwd[2000];
     if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){
-      fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20);
-      fossil_exit(1);
+      fossil_fatal("pwd too big: max %d\n", (int)sizeof(zPwd)-20);
     }
     blob_zero(pOut);
     blob_appendf(pOut, "%//%/", zPwd, zOrigName);
   }
   blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut)));
@@ -401,19 +425,19 @@
   blob_zero(&x);
   for(i=2; i<g.argc; i++){
     char zBuf[100];
     const char *zName = g.argv[i];
     file_canonical_name(zName, &x);
-    printf("[%s] -> [%s]\n", zName, blob_buffer(&x));
+    fossil_print("[%s] -> [%s]\n", zName, blob_buffer(&x));
     blob_reset(&x);
     sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_size(zName));
-    printf("  file_size   = %s\n", zBuf);
+    fossil_print("  file_size   = %s\n", zBuf);
     sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_mtime(zName));
-    printf("  file_mtime  = %s\n", zBuf);
-    printf("  file_isfile = %d\n", file_isfile(zName));
-    printf("  file_isexe  = %d\n", file_isexe(zName));
-    printf("  file_isdir  = %d\n", file_isdir(zName));
+    fossil_print("  file_mtime  = %s\n", zBuf);
+    fossil_print("  file_isfile = %d\n", file_isfile(zName));
+    fossil_print("  file_isexe  = %d\n", file_isexe(zName));
+    fossil_print("  file_isdir  = %d\n", file_isdir(zName));
   }
 }
 
 /*
 ** Return TRUE if the given filename is canonical.
@@ -453,12 +477,11 @@
   if( zPath[0]=='/' ){
     int i, j;
     Blob tmp;
     char zPwd[2000];
     if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){
-      fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20);
-      fossil_exit(1);
+      fossil_fatal("pwd too big: max %d\n", (int)sizeof(zPwd)-20);
     }
     for(i=1; zPath[i] && zPwd[i]==zPath[i]; i++){}
     if( zPath[i]==0 ){
       blob_reset(pOut);
       if( zPwd[i]==0 ){
@@ -502,11 +525,11 @@
   int i;
   Blob x;
   blob_zero(&x);
   for(i=2; i<g.argc; i++){
     file_relative_name(g.argv[i], &x);
-    printf("%s\n", blob_buffer(&x));
+    fossil_print("%s\n", blob_buffer(&x));
     blob_reset(&x);
   }
 }
 
 /*
@@ -557,11 +580,11 @@
   int i;
   Blob x;
   blob_zero(&x);
   for(i=2; i<g.argc; i++){
     if( file_tree_name(g.argv[i], &x, 1) ){
-      printf("%s\n", blob_buffer(&x));
+      fossil_print("%s\n", blob_buffer(&x));
       blob_reset(&x);
     }
   }
 }
 
@@ -620,17 +643,14 @@
   static const unsigned char zChars[] =
     "abcdefghijklmnopqrstuvwxyz"
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "0123456789";
   unsigned int i, j;
-  struct stat buf;
   const char *zDir = ".";
   
   for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
-    if( stat(azDirs[i], &buf) ) continue;
-    if( !S_ISDIR(buf.st_mode) ) continue;
-    if( access(azDirs[i], 07) ) continue;
+    if( !file_isdir(azDirs[i]) ) continue;
     zDir = azDirs[i];
     break;
   }
 
   /* Check that the output buffer is large enough for the temporary file 
@@ -646,11 +666,11 @@
     sqlite3_randomness(15, &zBuf[j]);
     for(i=0; i<15; i++, j++){
       zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
     }
     zBuf[j] = 0;
-  }while( access(zBuf,0)==0 );
+  }while( file_size(zBuf)<0 );
 }
 
 
 /*
 ** Return true if a file named zName exists and has identical content
@@ -668,5 +688,106 @@
   blob_read_from_file(&onDisk, zName);
   rc = blob_compare(&onDisk, pContent);
   blob_reset(&onDisk);
   return rc==0;
 }
+
+
+/**************************************************************************
+** The following routines translate between MBCS and UTF8 on windows.
+** Since everything is always UTF8 on unix, these routines are no-ops
+** there.
+*/
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+/*
+** Translate MBCS to UTF8.  Return a pointer to the translated text.  
+** Call fossil_mbcs_free() to deallocate any memory used to store the
+** returned pointer when done.
+*/
+char *fossil_mbcs_to_utf8(const char *zMbcs){
+#ifdef _WIN32
+  extern char *sqlite3_win32_mbcs_to_utf8(const char*);
+  return sqlite3_win32_mbcs_to_utf8(zMbcs);
+#else
+  return (char*)zMbcs;  /* No-op on unix */
+#endif  
+}
+
+/*
+** Translate UTF8 to MBCS for use in system calls.  Return a pointer to the
+** translated text..  Call fossil_mbcs_free() to deallocate any memory
+** used to store the returned pointer when done.
+*/
+char *fossil_utf8_to_mbcs(const char *zUtf8){
+#ifdef _WIN32
+  extern char *sqlite3_win32_utf8_to_mbcs(const char*);
+  return sqlite3_win32_utf8_to_mbcs(zUtf8);
+#else
+  return (char*)zUtf8;  /* No-op on unix */
+#endif  
+}
+
+/*
+** Translate UTF8 to MBCS for display on the console.  Return a pointer to the
+** translated text..  Call fossil_mbcs_free() to deallocate any memory
+** used to store the returned pointer when done.
+*/
+char *fossil_utf8_to_console(const char *zUtf8){
+#ifdef _WIN32
+  int nChar, nByte;
+  WCHAR *zUnicode;   /* Unicode version of zUtf8 */
+  char *zConsole;    /* Console version of zUtf8 */
+  int codepage;      /* Console code page */
+
+  nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0);
+  zUnicode = malloc( nChar*sizeof(zUnicode[0]) );
+  if( zUnicode==0 ){
+    return 0;
+  }
+  nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar);
+  if( nChar==0 ){
+    free(zUnicode);
+    return 0;
+  }
+  codepage = GetConsoleCP();
+  nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, 0, 0, 0, 0);
+  zConsole = malloc( nByte );
+  if( zConsole==0 ){
+    free(zUnicode);
+    return 0;
+  }
+  nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, zConsole, nByte, 0, 0);
+  free(zUnicode);
+  if( nByte == 0 ){
+    free(zConsole);
+    zConsole = 0;
+  }
+  return zConsole;
+#else
+  return (char*)zUtf8;  /* No-op on unix */
+#endif  
+}
+
+/*
+** Translate MBCS to UTF8.  Return a pointer.  Call fossil_mbcs_free()
+** to deallocate any memory used to store the returned pointer when done.
+*/
+void fossil_mbcs_free(char *zOld){
+#ifdef _WIN32
+  free(zOld);
+#else
+  /* No-op on unix */
+#endif  
+}
+
+/*
+** Like fopen() but always takes a UTF8 argument.
+*/
+FILE *fossil_fopen(const char *zName, const char *zMode){
+  char *zMbcs = fossil_utf8_to_mbcs(zName);
+  FILE *f = fopen(zMbcs, zMode);
+  fossil_mbcs_free(zMbcs);
+  return f;
+}

Index: src/finfo.c
==================================================================
--- src/finfo.c
+++ src/finfo.c
@@ -89,11 +89,11 @@
       blob_reset(&uuid);
     }else{
       blob_appendf(&line, "unknown 0000000000");
     }
     db_finalize(&q);
-    printf("%s\n", blob_str(&line));
+    fossil_print("%s\n", blob_str(&line));
     blob_reset(&fname);
     blob_reset(&line);
   }else if( find_option("print","p",0) ){
     Blob record;
     Blob fname;
@@ -152,21 +152,21 @@
         " ORDER BY event.mtime DESC LIMIT %d OFFSET %d",
         zFilename, iLimit, iOffset
     );
     blob_zero(&line);
     if( iBrief ){
-      printf("History of %s\n", blob_str(&fname));
+      fossil_print("History of %s\n", blob_str(&fname));
     }
     while( db_step(&q)==SQLITE_ROW ){
       const char *zFileUuid = db_column_text(&q, 0);
       const char *zCiUuid = db_column_text(&q,1);
       const char *zDate = db_column_text(&q, 2);
       const char *zCom = db_column_text(&q, 3);
       const char *zUser = db_column_text(&q, 4);
       char *zOut;
       if( iBrief ){
-        printf("%s ", zDate);
+        fossil_print("%s ", zDate);
         zOut = sqlite3_mprintf("[%.10s] %s (user: %s, artifact: [%.10s])",
                                zCiUuid, zCom, zUser, zFileUuid);
         comment_print(zOut, 11, 79);
         sqlite3_free(zOut);
       }else{

Index: src/glob.c
==================================================================
--- src/glob.c
+++ src/glob.c
@@ -250,15 +250,15 @@
 */
 void glob_test_cmd(void){
   Glob *pGlob;
   int i;
   if( g.argc<4 ) usage("PATTERN STRING ...");
-  printf("SQL expression: %s\n", glob_expr("x", g.argv[2]));
+  fossil_print("SQL expression: %s\n", glob_expr("x", g.argv[2]));
   pGlob = glob_create(g.argv[2]);
   for(i=0; i<pGlob->nPattern; i++){
-    printf("pattern[%d] = [%s]\n", i, pGlob->azPattern[i]);
+    fossil_print("pattern[%d] = [%s]\n", i, pGlob->azPattern[i]);
   }
   for(i=3; i<g.argc; i++){
-    printf("%d %s\n", glob_match(pGlob, g.argv[i]), g.argv[i]);
+    fossil_print("%d %s\n", glob_match(pGlob, g.argv[i]), g.argv[i]);
   }
   glob_free(pGlob);
 }

Index: src/http_transport.c
==================================================================
--- src/http_transport.c
+++ src/http_transport.c
@@ -120,11 +120,11 @@
       blob_appendf(&zCmd, " -P %d", g.urlPort);
 #else
       blob_appendf(&zCmd, " -p %d", g.urlPort);
 #endif
     }
-    printf("%s", blob_str(&zCmd));  /* Show the base of the SSH command */
+    fossil_print("%s", blob_str(&zCmd));  /* Show the base of the SSH command */
     if( g.urlUser && g.urlUser[0] ){
       zHost = mprintf("%s@%s", g.urlUser, g.urlName);
 #ifdef __MINGW32__
       /* Only win32 (and specifically PLINK.EXE) support the -pw option */
       if( g.urlPasswd && g.urlPasswd[0] ){
@@ -139,19 +139,19 @@
           blob_init(&pw, g.urlPasswd, -1);
         }
         blob_append(&zCmd, " -pw ", -1);
         shell_escape(&zCmd, blob_str(&pw));
         blob_reset(&pw);
-        printf(" -pw ********");  /* Do not show the password text */
+        fossil_print(" -pw ********");  /* Do not show the password text */
       }
 #endif
     }else{
       zHost = mprintf("%s", g.urlName);
     }
     blob_append(&zCmd, " ", 1);
     shell_escape(&zCmd, zHost);
-    printf(" %s\n", zHost);  /* Show the conclusion of the SSH command */
+    fossil_print(" %s\n", zHost);  /* Show the conclusion of the SSH command */
     free(zHost);
     popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
     if( sshPid==0 ){
       fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd);
     }
@@ -246,12 +246,12 @@
     }else if( g.urlIsFile ){
       if( transport.pFile ){ 
         fclose(transport.pFile);
         transport.pFile = 0;
       }
-      unlink(transport.zInFile);
-      unlink(transport.zOutFile);
+      file_delete(transport.zInFile);
+      file_delete(transport.zOutFile);
       free(transport.zInFile);
       free(transport.zOutFile);
     }else{
       socket_close();
     }

Index: src/import.c
==================================================================
--- src/import.c
+++ src/import.c
@@ -497,11 +497,11 @@
       gg.xFinish();
     }else
     if( memcmp(zLine, "progress ", 9)==0 ){
       gg.xFinish();
       trim_newline(&zLine[9]);
-      printf("%s\n", &zLine[9]);
+      fossil_print("%s\n", &zLine[9]);
       fflush(stdout);
     }else
     if( memcmp(zLine, "data ", 5)==0 ){
       fossil_free(gg.aData); gg.aData = 0;
       gg.nData = atoi(&zLine[5]);
@@ -697,11 +697,11 @@
   }else{
     pIn = stdin;
     fossil_binary_mode(pIn);
   }
   if( !incrFlag ){
-    if( forceFlag ) unlink(g.argv[2]);
+    if( forceFlag ) file_delete(g.argv[2]);
     db_create_repository(g.argv[2]);
   }
   db_open_repository(g.argv[2]);
   db_open_config(0);
 
@@ -742,19 +742,19 @@
     import_reset(0);
   }
   db_finalize(&q);
   db_end_transaction(0);
   db_begin_transaction();
-  printf("Rebuilding repository meta-data...\n");
+  fossil_print("Rebuilding repository meta-data...\n");
   rebuild_db(0, 1, !incrFlag);
   verify_cancel();
   db_end_transaction(0);
-  printf("Vacuuming..."); fflush(stdout);
+  fossil_print("Vacuuming..."); fflush(stdout);
   db_multi_exec("VACUUM");
-  printf(" ok\n");
+  fossil_print(" ok\n");
   if( !incrFlag ){
-    printf("project-id: %s\n", db_get("project-code", 0));
-    printf("server-id:  %s\n", db_get("server-code", 0));
+    fossil_print("project-id: %s\n", db_get("project-code", 0));
+    fossil_print("server-id:  %s\n", db_get("server-code", 0));
     zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
-    printf("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
+    fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
   }
 }

Index: src/info.c
==================================================================
--- src/info.c
+++ src/info.c
@@ -67,11 +67,11 @@
     zDate = db_text(0, 
       "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d",
       rid
     );
          /* 01234567890123 */
-    printf("%-13s %s %s\n", zUuidName, zUuid, zDate ? zDate : "");
+    fossil_print("%-13s %s %s\n", zUuidName, zUuid, zDate ? zDate : "");
     free(zUuid);
     free(zDate);
   }
   if( zUuid && showComment ){
     zComment = db_text(0, 
@@ -88,11 +88,11 @@
       const char *zUuid = db_column_text(&q, 0);
       zDate = db_text("", 
         "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d",
         db_column_int(&q, 1)
       );
-      printf("parent:       %s %s\n", zUuid, zDate);
+      fossil_print("parent:       %s %s\n", zUuid, zDate);
       free(zDate);
     }
     db_finalize(&q);
     db_prepare(&q, "SELECT uuid, cid FROM plink JOIN blob ON cid=rid "
                    " WHERE pid=%d", rid);
@@ -100,22 +100,22 @@
       const char *zUuid = db_column_text(&q, 0);
       zDate = db_text("", 
         "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d",
         db_column_int(&q, 1)
       );
-      printf("child:        %s %s\n", zUuid, zDate);
+      fossil_print("child:        %s %s\n", zUuid, zDate);
       free(zDate);
     }
     db_finalize(&q);
   }
   zTags = info_tags_of_checkin(rid, 0);
   if( zTags && zTags[0] ){
-    printf("tags:         %s\n", zTags);
+    fossil_print("tags:         %s\n", zTags);
   }
   free(zTags);
   if( zComment ){
-    printf("comment:      ");
+    fossil_print("comment:      ");
     comment_print(zComment, 14, 79);
     free(zComment);
   }
 }
 
@@ -141,33 +141,33 @@
   }
   if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){
     db_open_config(0);
     db_record_repository_filename(g.argv[2]);
     db_open_repository(g.argv[2]);
-    printf("project-name: %s\n", db_get("project-name", "<unnamed>"));
-    printf("project-code: %s\n", db_get("project-code", "<none>"));
-    printf("server-code:  %s\n", db_get("server-code", "<none>"));
+    fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>"));
+    fossil_print("project-code: %s\n", db_get("project-code", "<none>"));
+    fossil_print("server-code:  %s\n", db_get("server-code", "<none>"));
     return;
   }
   db_must_be_within_tree();
   if( g.argc==2 ){
     int vid;
          /* 012345678901234 */
     db_record_repository_filename(0);
-    printf("project-name: %s\n", db_get("project-name", "<unnamed>"));
-    printf("repository:   %s\n", db_lget("repository", ""));
-    printf("local-root:   %s\n", g.zLocalRoot);
+    fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>"));
+    fossil_print("repository:   %s\n", db_lget("repository", ""));
+    fossil_print("local-root:   %s\n", g.zLocalRoot);
 #if defined(_WIN32)
     if( g.zHome ){
-      printf("user-home:    %s\n", g.zHome);
+      fossil_print("user-home:    %s\n", g.zHome);
     }
 #endif
-    printf("project-code: %s\n", db_get("project-code", ""));
-    printf("server-code:  %s\n", db_get("server-code", ""));
+    fossil_print("project-code: %s\n", db_get("project-code", ""));
+    fossil_print("server-code:  %s\n", db_get("server-code", ""));
     vid = db_lget_int("checkout", 0);
     if( vid==0 ){
-      printf("checkout:     nil\n");
+      fossil_print("checkout:     nil\n");
     }else{
       show_common_info(vid, "checkout:", 1, 1);
     }
   }else{
     int rid;

Index: src/main.c
==================================================================
--- src/main.c
+++ src/main.c
@@ -227,23 +227,24 @@
 */
 int main(int argc, char **argv){
   const char *zCmdName = "unknown";
   int idx;
   int rc;
+  int i;
 
   sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
   g.now = time(0);
   g.argc = argc;
   g.argv = argv;
+  for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
   if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
     zCmdName = "cgi";
   }else if( argc<2 ){
-    fprintf(stderr, "Usage: %s COMMAND ...\n"
-                    "\"%s help\" for a list of available commands\n"
-                    "\"%s help COMMAND\" for specific details\n",
-                    argv[0], argv[0], argv[0]);
-    fossil_exit(1);
+    fossil_fatal("Usage: %s COMMAND ...\n"
+                 "\"%s help\" for a list of available commands\n"
+                 "\"%s help COMMAND\" for specific details\n",
+                 argv[0], argv[0], argv[0]);
   }else{
     g.fQuiet = find_option("quiet", 0, 0)!=0;
     g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
     g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
     if( g.fSqlTrace ) g.fSqlStats = 1;
@@ -264,14 +265,13 @@
     }
     zCmdName = g.argv[1];
   }
   rc = name_search(zCmdName, aCommand, count(aCommand), &idx);
   if( rc==1 ){
-    fprintf(stderr,"%s: unknown command: %s\n"
-                   "%s: use \"help\" for more information\n",
+    fossil_fatal("%s: unknown command: %s\n"
+                 "%s: use \"help\" for more information\n",
                    argv[0], zCmdName, argv[0]);
-    fossil_exit(1);
   }else if( rc==2 ){
     int i, n;
     Blob couldbe;
     blob_zero(&couldbe);
     n = strlen(zCmdName);
@@ -278,15 +278,14 @@
     for(i=0; i<count(aCommand); i++){
       if( memcmp(zCmdName, aCommand[i].zName, n)==0 ){
         blob_appendf(&couldbe, " %s", aCommand[i].zName);
       }
     }
-    fprintf(stderr,"%s: ambiguous command prefix: %s\n"
-                   "%s: could be any of:%s\n"
-                   "%s: use \"help\" for more information\n",
-                   argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]);
-    fossil_exit(1);
+    fossil_fatal("%s: ambiguous command prefix: %s\n"
+                 "%s: could be any of:%s\n"
+                 "%s: use \"help\" for more information\n",
+                 argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]);
   }
   aCommand[idx].xFunc();
   fossil_exit(0);
   /*NOT_REACHED*/
   return 0;
@@ -333,11 +332,12 @@
   if( g.cgiOutput && once ){
     once = 0;
     cgi_printf("<p class=\"generalError\">%h</p>", z);
     cgi_reply();
   }else{
-    fprintf(stderr, "%s: %s\n", fossil_nameofexe(), z);
+    char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z);
+    fossil_puts(zOut, 1);
   }
   db_force_rollback();
   fossil_exit(1);
 }
 void fossil_fatal(const char *zFormat, ...){
@@ -350,11 +350,12 @@
   if( g.cgiOutput ){
     g.cgiOutput = 0;
     cgi_printf("<p class=\"generalError\">%h</p>", z);
     cgi_reply();
   }else{
-    fprintf(stderr, "\r%s: %s\n", fossil_nameofexe(), z);
+    char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z);
+    fossil_puts(zOut, 1);
   }
   db_force_rollback();
   fossil_exit(1);
 }
 
@@ -378,11 +379,12 @@
   if( g.cgiOutput ){
     g.cgiOutput = 0;
     cgi_printf("<p class=\"generalError\">%h</p>", z);
     cgi_reply();
   }else{
-    fprintf(stderr, "\r%s: %s\n", fossil_nameofexe(), z);
+    char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z);
+    fossil_puts(zOut, 1);
   }
   db_force_rollback();
   fossil_exit(1);
 }
 
@@ -395,11 +397,13 @@
   z = vmprintf(zFormat, ap);
   va_end(ap);
   if( g.cgiOutput ){
     cgi_printf("<p class=\"generalError\">%h</p>", z);
   }else{
-    fprintf(stderr, "\r%s: %s\n", fossil_nameofexe(), z);
+    char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z);
+    fossil_puts(zOut, 1);
+    free(zOut);
   }
 }
 
 /*
 ** Malloc and free routines that cannot fail
@@ -426,11 +430,13 @@
 #if defined(_WIN32)
   /* On windows, we have to put double-quotes around the entire command.
   ** Who knows why - this is just the way windows works.
   */
   char *zNewCmd = mprintf("\"%s\"", zOrigCmd);
-  rc = system(zNewCmd);
+  char *zMbcs = fossil_utf8_to_mbcs(zNewCmd);
+  rc = system(zMbcs);
+  fossil_mbcs_free(zMbcs);
   free(zNewCmd);
 #else
   /* On unix, evaluate the command directly.
   */
   rc = system(zOrigCmd);
@@ -507,12 +513,11 @@
 
 /*
 ** Print a usage comment and quit
 */
 void usage(const char *zFormat){
-  fprintf(stderr, "Usage: %s %s %s\n", fossil_nameofexe(), g.argv[1], zFormat);
-  fossil_exit(1);
+  fossil_fatal("Usage: %s %s %s\n", fossil_nameofexe(), g.argv[1], zFormat);
 }
 
 /*
 ** Remove n elements from g.argv beginning with the i-th element.
 */
@@ -601,14 +606,14 @@
   if( nCol==0 ) nCol = 1;
   nRow = (nWord + nCol - 1)/nCol;
   for(i=0; i<nRow; i++){
     const char *zSpacer = "";
     for(j=i; j<nWord; j+=nRow){
-      printf("%s%-*s", zSpacer, mxLen, azWord[j]);
+      fossil_print("%s%-*s", zSpacer, mxLen, azWord[j]);
       zSpacer = "  ";
     }
-    printf("\n");
+    fossil_print("\n");
   }
 }
 
 /*
 ** List of commands starting with zPrefix, or all commands if zPrefix is NULL.
@@ -650,11 +655,12 @@
 ** Usage: %fossil version
 **
 ** Print the source code version number for the fossil executable.
 */
 void version_cmd(void){
-  printf("This is fossil version " MANIFEST_VERSION " " MANIFEST_DATE " UTC\n");
+  fossil_print("This is fossil version "
+                MANIFEST_VERSION " " MANIFEST_DATE " UTC\n");
 }
 
 
 /*
 ** COMMAND: help
@@ -665,12 +671,12 @@
 */
 void help_cmd(void){
   int rc, idx;
   const char *z;
   if( g.argc<3 ){
-    printf("Usage: %s help COMMAND.\nAvailable COMMANDs:\n",
-           fossil_nameofexe());
+    fossil_print("Usage: %s help COMMAND.\nAvailable COMMANDs:\n",
+                 fossil_nameofexe());
     cmd_cmd_list(0);
     version_cmd();
     return;
   }
   rc = name_search(g.argv[2], aCommand, count(aCommand), &idx);
@@ -689,11 +695,11 @@
     fossil_fatal("no help available for the %s command",
        aCommand[idx].zName);
   }
   while( *z ){
     if( *z=='%' && strncmp(z, "%fossil", 7)==0 ){
-      printf("%s", fossil_nameofexe());
+      fossil_print("%s", fossil_nameofexe());
       z += 7;
     }else{
       putchar(*z);
       z++;
     }
@@ -1281,12 +1287,12 @@
   if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){
     fossil_fatal("no repository specified");
   }
   g.fullHttpReply = 1;
   if( g.argc==6 ){
-    g.httpIn = fopen(g.argv[3], "rb");
-    g.httpOut = fopen(g.argv[4], "wb");
+    g.httpIn = fossil_fopen(g.argv[3], "rb");
+    g.httpOut = fossil_fopen(g.argv[4], "wb");
     zIpAddr = g.argv[5];
   }else{
     g.httpIn = stdin;
     g.httpOut = stdout;
     zIpAddr = 0;
@@ -1327,11 +1333,11 @@
   int bExists;
   while( zPath && zPath[0] ){
     while( zPath[0]==':' ) zPath++;
     for(i=0; zPath[i] && zPath[i]!=':'; i++){}
     zFull = mprintf("%.*s/%s", i, zPath, zBinary);
-    bExists = access(zFull, X_OK);
+    bExists = file_access(zFull, X_OK);
     free(zFull);
     if( bExists==0 ) return 1;
     zPath += i;
   }
   return 0;
@@ -1455,8 +1461,8 @@
 ** wildcard expansion behavior of the host shell can be investigated.
 */
 void test_echo_cmd(void){
   int i;
   for(i=0; i<g.argc; i++){
-    printf("argv[%d] = [%s]\n", i, g.argv[i]);
+    fossil_print("argv[%d] = [%s]\n", i, g.argv[i]);
   }
 }

Index: src/main.mk
==================================================================
--- src/main.mk
+++ src/main.mk
@@ -892,13 +892,13 @@
 $(OBJDIR)/zip.h:	$(OBJDIR)/headers
 $(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c
 	$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT2 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o
 
 $(OBJDIR)/shell.o:	$(SRCDIR)/shell.c
-	$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
+	$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -Dfopen=fossil_fopen -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
 
 $(OBJDIR)/th.o:	$(SRCDIR)/th.c
 	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o
 
 $(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
 	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o
 

Index: src/makemake.tcl
==================================================================
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -250,10 +250,11 @@
 writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"
 
 writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c"
 set opt {-Dmain=sqlite3_shell}
 append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
+append opt " -Dfopen=fossil_fopen"
 writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
 
 writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
 writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"
 

Index: src/md5.c
==================================================================
--- src/md5.c
+++ src/md5.c
@@ -376,11 +376,11 @@
   FILE *in;
   MD5Context ctx;
   unsigned char zResult[16];
   char zBuf[10240];
 
-  in = fopen(zFilename,"rb");
+  in = fossil_fopen(zFilename,"rb");
   if( in==0 ){
     return 1;
   }
   MD5Init(&ctx);
   for(;;){
@@ -438,9 +438,9 @@
       blob_read_from_channel(&in, stdin, -1);
       md5sum_blob(&in, &cksum);
     }else{
       md5sum_file(g.argv[i], &cksum);
     }
-    printf("%s  %s\n", blob_str(&cksum), g.argv[i]);
+    fossil_print("%s  %s\n", blob_str(&cksum), g.argv[i]);
     blob_reset(&cksum);
   }
 }

Index: src/merge.c
==================================================================
--- src/merge.c
+++ src/merge.c
@@ -249,20 +249,20 @@
   if( debugFlag ){
     db_prepare(&q,
        "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, isexe FROM fv"
     );
     while( db_step(&q)==SQLITE_ROW ){
-       printf("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d\n",
+       fossil_print("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d\n",
           db_column_int(&q, 0),
           db_column_int(&q, 5),
           db_column_int(&q, 6),
           db_column_int(&q, 7),
           db_column_int(&q, 4),
           db_column_int(&q, 8));
-       printf("     fn  = [%s]\n", db_column_text(&q, 1));
-       printf("     fnp = [%s]\n", db_column_text(&q, 2));
-       printf("     fnm = [%s]\n", db_column_text(&q, 3));
+       fossil_print("     fn  = [%s]\n", db_column_text(&q, 1));
+       fossil_print("     fnp = [%s]\n", db_column_text(&q, 2));
+       fossil_print("     fnm = [%s]\n", db_column_text(&q, 3));
     }
     db_finalize(&q);
   }
 
   /*
@@ -274,11 +274,11 @@
     "SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0"
   );
   while( db_step(&q)==SQLITE_ROW ){
     int idm = db_column_int(&q, 0);
     char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idm);
-    printf("WARNING - no common ancestor: %s\n", zName);
+    fossil_warning("WARNING - no common ancestor: %s\n", zName);
     free(zName);
     db_multi_exec("UPDATE fv SET idm=0 WHERE idm=%d", idm);
   }
   db_finalize(&q);
 
@@ -300,11 +300,11 @@
       vid, idm
     );
     idv = db_last_insert_rowid();
     db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
     zName = db_column_text(&q, 2);
-    printf("ADDED %s\n", zName);
+    fossil_print("ADDED %s\n", zName);
     if( !nochangeFlag ){
       undo_save(zName);
       vfile_to_disk(0, idm, 0, 0);
     }
   }
@@ -322,11 +322,11 @@
   while( db_step(&q)==SQLITE_ROW ){
     int idv = db_column_int(&q, 0);
     int ridm = db_column_int(&q, 1);
     const char *zName = db_column_text(&q, 2);
     /* Copy content from idm over into idv.  Overwrite idv. */
-    printf("UPDATE %s\n", zName);
+    fossil_print("UPDATE %s\n", zName);
     if( !nochangeFlag ){
       undo_save(zName);
       db_multi_exec(
         "UPDATE vfile SET mtime=0, mrid=%d, chnged=2 WHERE id=%d", ridm, idv
       );
@@ -355,13 +355,14 @@
     int rc;
     char *zFullPath;
     Blob m, p, r;
     /* Do a 3-way merge of idp->idm into idp->idv.  The results go into idv. */
     if( detailFlag ){
-      printf("MERGE %s  (pivot=%d v1=%d v2=%d)\n", zName, ridp, ridm, ridv);
+      fossil_print("MERGE %s  (pivot=%d v1=%d v2=%d)\n", 
+                   zName, ridp, ridm, ridv);
     }else{
-      printf("MERGE %s\n", zName);
+      fossil_print("MERGE %s\n", zName);
     }
     undo_save(zName);
     zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
     content_get(ridp, &p);
     content_get(ridm, &m);
@@ -376,15 +377,15 @@
         blob_write_to_file(&r, zFullPath);
         file_setexe(zFullPath, isExe);
       }
       db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv);
       if( rc>0 ){
-        printf("***** %d merge conflicts in %s\n", rc, zName);
+        fossil_print("***** %d merge conflicts in %s\n", rc, zName);
         nConflict++;
       }
     }else{
-      printf("***** Cannot merge binary file %s\n", zName);
+      fossil_print("***** Cannot merge binary file %s\n", zName);
       nConflict++;
     }
     blob_reset(&p);
     blob_reset(&m);
     blob_reset(&r);
@@ -403,22 +404,22 @@
   while( db_step(&q)==SQLITE_ROW ){
     int idv = db_column_int(&q, 0);
     const char *zName = db_column_text(&q, 1);
     int chnged = db_column_int(&q, 2);
     /* Delete the file idv */
-    printf("DELETE %s\n", zName);
+    fossil_print("DELETE %s\n", zName);
     if( chnged ){
-      printf("WARNING: local edits lost for %s\n", zName);
+      fossil_warning("WARNING: local edits lost for %s\n", zName);
       nConflict++;
     }
     undo_save(zName);
     db_multi_exec(
       "UPDATE vfile SET deleted=1 WHERE id=%d", idv
     );
     if( !nochangeFlag ){
       char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
-      unlink(zFullPath);
+      file_delete(zFullPath);
       free(zFullPath);
     }
   }
   db_finalize(&q);
 
@@ -433,11 +434,11 @@
   );
   while( db_step(&q)==SQLITE_ROW ){
     int idv = db_column_int(&q, 0);
     const char *zOldName = db_column_text(&q, 1);
     const char *zNewName = db_column_text(&q, 2);
-    printf("RENAME %s -> %s\n", zOldName, zNewName);
+    fossil_print("RENAME %s -> %s\n", zOldName, zNewName);
     undo_save(zOldName);
     undo_save(zNewName);
     db_multi_exec(
       "UPDATE vfile SET pathname=%Q, origname=coalesce(origname,pathname)"
       " WHERE id=%d AND vid=%d", zNewName, idv, vid
@@ -444,11 +445,11 @@
     );
     if( !nochangeFlag ){
       char *zFullOldPath = mprintf("%s%s", g.zLocalRoot, zOldName);
       char *zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName);
       file_copy(zFullOldPath, zFullNewPath);
-      unlink(zFullOldPath);
+      file_delete(zFullOldPath);
       free(zFullNewPath);
       free(zFullOldPath);
     }
   }
   db_finalize(&q);
@@ -455,11 +456,12 @@
 
 
   /* Report on conflicts
   */
   if( nConflict && !nochangeFlag ){
-    printf("WARNING: merge conflicts - see messages above for details.\n");
+    fossil_warning(
+       "WARNING: merge conflicts - see messages above for details.\n");
   }
 
   /*
   ** Clean up the mid and pid VFILE entries.  Then commit the changes.
   */

Index: src/merge3.c
==================================================================
--- src/merge3.c
+++ src/merge3.c
@@ -314,25 +314,21 @@
   Blob pivot, v1, v2, merged;
   if( g.argc!=6 ){
     usage("PIVOT V1 V2 MERGED");
   }
   if( blob_read_from_file(&pivot, g.argv[2])<0 ){
-    fprintf(stderr,"cannot read %s\n", g.argv[2]);
-    fossil_exit(1);
+    fossil_fatal("cannot read %s\n", g.argv[2]);
   }
   if( blob_read_from_file(&v1, g.argv[3])<0 ){
-    fprintf(stderr,"cannot read %s\n", g.argv[3]);
-    fossil_exit(1);
+    fossil_fatal("cannot read %s\n", g.argv[3]);
   }
   if( blob_read_from_file(&v2, g.argv[4])<0 ){
-    fprintf(stderr,"cannot read %s\n", g.argv[4]);
-    fossil_exit(1);
+    fossil_fatal("cannot read %s\n", g.argv[4]);
   }
   blob_merge(&pivot, &v1, &v2, &merged);
   if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){
-    fprintf(stderr,"cannot write %s\n", g.argv[4]);
-    fossil_exit(1);
+    fossil_fatal("cannot write %s\n", g.argv[4]);
   }
   blob_reset(&pivot);
   blob_reset(&v1);
   blob_reset(&v2);
   blob_reset(&merged);
@@ -428,14 +424,14 @@
       zCmd = string_subst(zGMerge, 8, azSubst);
       printf("%s\n", zCmd); fflush(stdout);
       fossil_system(zCmd);
       if( file_size(zOut)>=0 ){
         blob_read_from_file(pOut, zOut);
-        unlink(zPivot);
-        unlink(zOrig);
-        unlink(zOther);
-        unlink(zOut);
+        file_delete(zPivot);
+        file_delete(zOrig);
+        file_delete(zOther);
+        file_delete(zOut);
       }
       fossil_free(zCmd);
       fossil_free(zOut);
     }
     fossil_free(zPivot);

Index: src/name.c
==================================================================
--- src/name.c
+++ src/name.c
@@ -267,16 +267,16 @@
   int i;
   Blob name;
   db_must_be_within_tree();
   for(i=2; i<g.argc; i++){
     blob_init(&name, g.argv[i], -1);
-    printf("%s -> ", g.argv[i]);
+    fossil_print("%s -> ", g.argv[i]);
     if( name_to_uuid(&name, 1) ){
-      printf("ERROR: %s\n", g.zErrMsg);
+      fossil_print("ERROR: %s\n", g.zErrMsg);
       fossil_error_reset();
     }else{
-      printf("%s\n", blob_buffer(&name));
+      fossil_print("%s\n", blob_buffer(&name));
     }
     blob_reset(&name);
   }
 }
 

Index: src/path.c
==================================================================
--- src/path.c
+++ src/path.c
@@ -213,16 +213,17 @@
     z = db_text(0,
       "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)"
       "  FROM blob, event"
       " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'",
       p->rid, p->rid);
-    printf("%4d: %s", n, z);
+    fossil_print("%4d: %s", n, z);
     fossil_free(z);
     if( p->u.pTo ){
-      printf(" is a %s of\n", p->u.pTo->fromIsParent ? "parent" : "child");
+      fossil_print(" is a %s of\n", 
+                   p->u.pTo->fromIsParent ? "parent" : "child");
     }else{
-      printf("\n");
+      fossil_print("\n");
     }
   }
 }
 
 /*
@@ -312,16 +313,16 @@
     z = db_text(0,
       "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)"
       "  FROM blob, event"
       " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'",
       p->rid, p->rid);
-    printf("%4d: %s", n, z);
+    fossil_print("%4d: %s", n, z);
     fossil_free(z);
-    if( p->rid==iFrom ) printf(" VERSION1");
-    if( p->rid==iTo ) printf(" VERSION2");
-    if( p->rid==iPivot ) printf(" PIVOT");
-    printf("\n");
+    if( p->rid==iFrom ) fossil_print(" VERSION1");
+    if( p->rid==iTo ) fossil_print(" VERSION2");
+    if( p->rid==iPivot ) fossil_print(" PIVOT");
+    fossil_print("\n");
   }
 }
 
 
 /*
@@ -445,11 +446,11 @@
   for(i=0; i<nChng; i++){
     char *zFrom, *zTo;
 
     zFrom = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2]);
     zTo = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2+1]);
-    printf("[%s] -> [%s]\n", zFrom, zTo);
+    fossil_print("[%s] -> [%s]\n", zFrom, zTo);
     fossil_free(zFrom);
     fossil_free(zTo);
   }
   fossil_free(aChng);
 }

Index: src/printf.c
==================================================================
--- src/printf.c
+++ src/printf.c
@@ -797,10 +797,36 @@
 void fossil_error_reset(void){
   free(g.zErrMsg);
   g.zErrMsg = 0;
   g.iErrPriority = 0;
 }
+
+/*
+** Write to standard output or standard error.
+**
+** On windows, transform the output into the current terminal encoding
+** if the output is going to the screen.  If output is redirected into
+** a file, no translation occurs.  No translation ever occurs on unix.
+*/
+void fossil_puts(const char *z, int toStdErr){
+#if defined(_WIN32)
+  static int once = 1;
+  static int istty[2];
+  char *zToFree = 0;
+  if( once ){
+    istty[0] = _isatty(fileno(stdout));
+    istty[1] = _isatty(fileno(stderr));
+    once = 0;
+  }
+  assert( toStdErr==0 || toStdErr==1 );
+  if( istty[toStdErr] ) z = zToFree = fossil_utf8_to_console(z);
+  fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout);
+  free(zToFree);
+#else
+  fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout);
+#endif
+}
 
 /*
 ** Write output for user consumption.  If g.cgiOutput is enabled, then
 ** send the output as part of the CGI reply.  If g.cgiOutput is false,
 ** then write on standard output.
@@ -811,11 +837,11 @@
   if( g.cgiOutput ){
     cgi_vprintf(zFormat, ap);
   }else{
     Blob b = empty_blob;
     vxprintf(&b, zFormat, ap);
-    fwrite(blob_buffer(&b), 1, blob_size(&b), stdout);
+    fossil_puts(blob_str(&b), 0);
     blob_reset(&b);
   }
 }
 
 /*

Index: src/rebuild.c
==================================================================
--- src/rebuild.c
+++ src/rebuild.c
@@ -176,11 +176,11 @@
 ** The input is actually the permill complete.
 */
 static void percent_complete(int permill){
   static int lastOutput = -1;
   if( permill>lastOutput ){
-    printf("  %d.%d%% complete...\r", permill/10, permill%10);
+    fossil_print("  %d.%d%% complete...\r", permill/10, permill%10);
     fflush(stdout);
     lastOutput = permill;
   }
 }
 
@@ -420,11 +420,11 @@
   if( !g.fQuiet && totalSize>0 ){
     processCnt += incrSize;
     percent_complete((processCnt*1000)/totalSize);
   }
   if(!g.fQuiet && ttyOutput ){
-    printf("\n");
+    fossil_print("\n");
   }
   return errCnt;
 }
 
 /*
@@ -549,32 +549,34 @@
     "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());"
     "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());",
     CONTENT_SCHEMA, AUX_SCHEMA
   );
   if( errCnt && !forceFlag ){
-    printf("%d errors. Rolling back changes. Use --force to force a commit.\n",
-            errCnt);
+    fossil_print(
+      "%d errors. Rolling back changes. Use --force to force a commit.\n",
+      errCnt
+    );
     db_end_transaction(1);
   }else{
     if( runCompress ){
-      printf("Extra delta compression... "); fflush(stdout);
+      fossil_print("Extra delta compression... "); fflush(stdout);
       extra_deltification();
       runVacuum = 1;
     }
     if( omitVerify ) verify_cancel();
     db_end_transaction(0);
-    if( runCompress ) printf("done\n");
+    if( runCompress ) fossil_print("done\n");
     db_close(0);
     db_open_repository(g.zRepositoryName);
     if( newPagesize ){
       db_multi_exec("PRAGMA page_size=%d", newPagesize);
       runVacuum = 1;
     }
     if( runVacuum ){
-      printf("Vacuuming the database... "); fflush(stdout);
+      fossil_print("Vacuuming the database... "); fflush(stdout);
       db_multi_exec("VACUUM");
-      printf("done\n");
+      fossil_print("done\n");
     }
     if( activateWal ){
       db_multi_exec("PRAGMA journal_mode=WAL;");
     }
   }
@@ -678,16 +680,16 @@
     manifest_destroy(p);
   }
   n = db_int(0, "SELECT count(*) FROM /*scan*/"
                 "  (SELECT rid FROM blob EXCEPT SELECT x FROM xdone)");
   if( n==0 ){
-    printf("all artifacts reachable through clusters\n");
+    fossil_print("all artifacts reachable through clusters\n");
   }else{
-    printf("%d unreachable artifacts:\n", n);
+    fossil_print("%d unreachable artifacts:\n", n);
     db_prepare(&q, "SELECT rid, uuid FROM blob WHERE rid NOT IN xdone");
     while( db_step(&q)==SQLITE_ROW ){
-      printf("  %3d %s\n", db_column_int(&q,0), db_column_text(&q,1));
+      fossil_print("  %3d %s\n", db_column_int(&q,0), db_column_text(&q,1));
     }
     db_finalize(&q);
   }
 }
 
@@ -797,11 +799,11 @@
       }
       content_put(&aContent);
       blob_reset(&path);
       blob_reset(&aContent);
       free(zSubpath);
-      printf("\r%d", ++nFileRead);
+      fossil_print("\r%d", ++nFileRead);
       fflush(stdout);
     }
     closedir(d);
   }else {
     fossil_panic("encountered error %d while trying to open \"%s\".",
@@ -824,22 +826,22 @@
   char *zPassword;
   if( g.argc!=4 ){
     usage("FILENAME DIRECTORY");
   }
   if( file_isdir(g.argv[3])!=1 ){
-    printf("\"%s\" is not a directory\n\n", g.argv[3]);
+    fossil_print("\"%s\" is not a directory\n\n", g.argv[3]);
     usage("FILENAME DIRECTORY");
   }
   db_create_repository(g.argv[2]);
   db_open_repository(g.argv[2]);
   db_open_config(0);
   db_begin_transaction();
   db_initial_setup(0, 0, 1);
 
-  printf("Reading files from directory \"%s\"...\n", g.argv[3]);
+  fossil_print("Reading files from directory \"%s\"...\n", g.argv[3]);
   recon_read_dir(g.argv[3]);
-  printf("\nBuilding the Fossil repository...\n");
+  fossil_print("\nBuilding the Fossil repository...\n");
 
   rebuild_db(0, 1, 1);
 
   /* Reconstruct the private table.  The private table contains the rid
   ** of every manifest that is tagged with "private" and every file that
@@ -861,14 +863,14 @@
   ** long time.
   */
   verify_cancel();
   
   db_end_transaction(0);
-  printf("project-id: %s\n", db_get("project-code", 0));
-  printf("server-id: %s\n", db_get("server-code", 0));
+  fossil_print("project-id: %s\n", db_get("project-code", 0));
+  fossil_print("server-id: %s\n", db_get("server-code", 0));
   zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
-  printf("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword);
+  fossil_print("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword);
 }
 
 /*
 ** COMMAND: deconstruct
 **
@@ -909,11 +911,11 @@
     }else{
       fossil_fatal("N(%s) is not a a valid prefix length!",zPrefixOpt);
     }
   }
 #ifndef _WIN32
-  if( access(zDestDir, W_OK) ){
+  if( file_access(zDestDir, W_OK) ){
     fossil_fatal("DESTINATION(%s) is not writeable!",zDestDir);
   }
 #else
   /* write access on windows is not checked, errors will be
   ** dected on blob_write_to_file
@@ -928,11 +930,11 @@
   db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
   bag_init(&bagDone);
   ttyOutput = 1;
   processCnt = 0;
   if (!g.fQuiet) {
-    printf("0 (0%%)...\r");
+    fossil_print("0 (0%%)...\r");
     fflush(stdout);
   }
   totalSize = db_int(0, "SELECT count(*) FROM blob");
   db_prepare(&s,
      "SELECT rid, size FROM blob /*scan*/"
@@ -964,12 +966,12 @@
       }
     }
   }
   db_finalize(&s);
   if(!g.fQuiet && ttyOutput ){
-    printf("\n");
+    fossil_print("\n");
   }
 
   /* free filename format string */
   free(zFNameFormat);
   zFNameFormat = 0;
 }

Index: src/report.c
==================================================================
--- src/report.c
+++ src/report.c
@@ -1000,19 +1000,19 @@
 */
 void rpt_list_reports(void){
   Stmt q;
   char const aRptOutFrmt[] = "%s\t%s\n";
 
-  printf("Available reports:\n");
-  printf(aRptOutFrmt,"report number","report title");
-  printf(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle);
+  fossil_print("Available reports:\n");
+  fossil_print(aRptOutFrmt,"report number","report title");
+  fossil_print(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle);
   db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn");
   while( db_step(&q)==SQLITE_ROW ){
     const char *zRn = db_column_text(&q, 0);
     const char *zTitle = db_column_text(&q, 1);
 
-    printf(aRptOutFrmt,zRn,zTitle);
+    fossil_print(aRptOutFrmt,zRn,zTitle);
   }
   db_finalize(&q);
 }
 
 /*
@@ -1037,25 +1037,25 @@
     case tktFossilize:
       { char *zFosZ;
 
         if( z && *z ){
           zFosZ = fossilize(z,-1);
-          printf("%s",zFosZ);
+          fossil_print("%s",zFosZ);
           free(zFosZ);
         }
         break;
       }
     default:
       while( z && z[0] ){
         int i, j;
         for(i=0; z[i] && (!fossil_isspace(z[i]) || z[i]==' '); i++){}
         if( i>0 ){
-          printf("%.*s", i, z);
+          fossil_print("%.*s", i, z);
         }
         for(j=i; fossil_isspace(z[j]); j++){}
         if( j>i ){
-          printf("%*s", j-i, "");
+          fossil_print("%*s", j-i, "");
         }
         z += j;
       }
       break; 
   }
@@ -1074,17 +1074,17 @@
   int i;
 
   if( *pCount==0 ){
     for(i=0; i<nArg; i++){
       output_no_tabs_file(azName[i]);
-      printf("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n");
+      fossil_print("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n");
     }
   }
   ++*pCount;
   for(i=0; i<nArg; i++){
     output_no_tabs_file(azArg[i]);
-    printf("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n");
+    fossil_print("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n");
   }
   return 0;
 }
 
 /*

Index: src/sha1.c
==================================================================
--- src/sha1.c
+++ src/sha1.c
@@ -266,11 +266,11 @@
   FILE *in;
   SHA1Context ctx;
   unsigned char zResult[20];
   char zBuf[10240];
 
-  in = fopen(zFilename,"rb");
+  in = fossil_fopen(zFilename,"rb");
   if( in==0 ){
     return 1;
   }
   SHA1Init(&ctx);
   for(;;){
@@ -430,9 +430,9 @@
       blob_read_from_channel(&in, stdin, -1);
       sha1sum_blob(&in, &cksum);
     }else{
       sha1sum_file(g.argv[i], &cksum);
     }
-    printf("%s  %s\n", blob_str(&cksum), g.argv[i]);
+    fossil_print("%s  %s\n", blob_str(&cksum), g.argv[i]);
     blob_reset(&cksum);
   }
 }

Index: src/stash.c
==================================================================
--- src/stash.c
+++ src/stash.c
@@ -185,33 +185,33 @@
     blob_zero(&delta);
     if( rid==0 ){
       db_ephemeral_blob(&q, 5, &delta);
       blob_write_to_file(&delta, zNPath);
       file_setexe(zNPath, isExec);
-      printf("ADD %s\n", zNew);
+      fossil_print("ADD %s\n", zNew);
     }else if( isRemoved ){
-      printf("DELETE %s\n", zOrig);
-      unlink(zOPath);
+      fossil_print("DELETE %s\n", zOrig);
+      file_delete(zOPath);
     }else{
       Blob a, b, out, disk;
       db_ephemeral_blob(&q, 5, &delta);
       blob_read_from_file(&disk, zOPath);     
       content_get(rid, &a);
       blob_delta_apply(&a, &delta, &b);
       if( blob_compare(&disk, &a)==0 ){
         blob_write_to_file(&b, zNPath);
         file_setexe(zNPath, isExec);
-        printf("UPDATE %s\n", zNew);
+        fossil_print("UPDATE %s\n", zNew);
       }else{
         int rc = merge_3way(&a, zOPath, &b, &out);
         blob_write_to_file(&out, zNPath);
         file_setexe(zNPath, isExec);
         if( rc ){
-          printf("CONFLICT %s\n", zNew);
+          fossil_print("CONFLICT %s\n", zNew);
           nConflict++;
         }else{
-          printf("MERGE %s\n", zNew);
+          fossil_print("MERGE %s\n", zNew);
         }
         blob_reset(&out);
       }
       blob_reset(&a);
       blob_reset(&b);
@@ -218,16 +218,16 @@
       blob_reset(&disk);
     }
     blob_reset(&delta);
     if( fossil_strcmp(zOrig,zNew)!=0 ){
       undo_save(zOrig);
-      unlink(zOPath);
+      file_delete(zOPath);
     }
   }
   db_finalize(&q);
   if( nConflict ){
-    printf("WARNING: merge conflicts - see messages above for details.\n");
+    fossil_print("WARNING: merge conflicts - see messages above for details.\n");
   }
 }
 
 /*
 ** Show the diffs associate with a single stash.
@@ -248,25 +248,25 @@
     const char *zNew = db_column_text(&q, 4);
     char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig);
     Blob delta;
     if( rid==0 ){
       db_ephemeral_blob(&q, 5, &delta);
-      printf("ADDED %s\n", zNew);
+      fossil_print("ADDED %s\n", zNew);
       diff_print_index(zNew);
       diff_file_mem(&empty, &delta, zNew, zDiffCmd, 0);
     }else if( isRemoved ){
-      printf("DELETE %s\n", zOrig);
+      fossil_print("DELETE %s\n", zOrig);
       blob_read_from_file(&delta, zOPath);
       diff_print_index(zNew);
       diff_file_mem(&delta, &empty, zOrig, zDiffCmd, 0);
     }else{
       Blob a, b, disk;
       db_ephemeral_blob(&q, 5, &delta);
       blob_read_from_file(&disk, zOPath);     
       content_get(rid, &a);
       blob_delta_apply(&a, &delta, &b);
-      printf("CHANGED %s\n", zNew);
+      fossil_print("CHANGED %s\n", zNew);
       diff_file_mem(&disk, &b, zNew, zDiffCmd, 0);
       blob_reset(&a);
       blob_reset(&b);
       blob_reset(&disk);
     }
@@ -413,23 +413,23 @@
        " ORDER BY ctime DESC"
     );
     while( db_step(&q)==SQLITE_ROW ){
       const char *zCom;
       n++;
-      printf("%5d: [%.14s] on %s\n",
+      fossil_print("%5d: [%.14s] on %s\n",
         db_column_int(&q, 0),
         db_column_text(&q, 1),
         db_column_text(&q, 3)
       );
       zCom = db_column_text(&q, 2);
       if( zCom && zCom[0] ){
-        printf("       ");
+        fossil_print("       ");
         comment_print(zCom, 7, 79);
       }
     }
     db_finalize(&q);
-    if( n==0 ) printf("empty stash\n");
+    if( n==0 ) fossil_print("empty stash\n");
   }else
   if( memcmp(zCmd, "drop", nCmd)==0 ){
     int allFlag = find_option("all", 0, 0)!=0;
     if( g.argc>4 ) usage("stash apply STASHID");
     if( allFlag ){

Index: src/sync.c
==================================================================
--- src/sync.c
+++ src/sync.c
@@ -76,11 +76,11 @@
     ** autosync, or something?
     */
     configSync = CONFIGSET_SHUN;
   }
 #endif
-  printf("Autosync:  %s\n", g.urlCanonical);
+  fossil_print("Autosync:  %s\n", g.urlCanonical);
   url_enable_proxy("via proxy: ");
   rc = client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, configSync, 0);
   if( rc ) fossil_warning("Autosync failed");
   return rc;
 }
@@ -124,11 +124,11 @@
     db_set("last-sync-url", g.urlCanonical, 0);
     if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0);
   }
   user_select();
   if( g.argc==2 ){
-    printf("Server:    %s\n", g.urlCanonical);
+    fossil_print("Server:    %s\n", g.urlCanonical);
   }
   url_enable_proxy("via proxy: ");
   *pConfigSync = configSync;
 }
 
@@ -263,12 +263,12 @@
       }
     }
   }
   zUrl = db_get("last-sync-url", 0);
   if( zUrl==0 ){
-    printf("off\n");
+    fossil_print("off\n");
     return;
   }else{
     url_parse(zUrl);
-    printf("%s\n", g.urlCanonical);
+    fossil_print("%s\n", g.urlCanonical);
   }
 }

Index: src/tag.c
==================================================================
--- src/tag.c
+++ src/tag.c
@@ -438,11 +438,11 @@
         "   AND tagxref.tagtype>0"
         "   AND blob.rid=tagxref.rid",
         g.argv[3]
       );
       while( db_step(&q)==SQLITE_ROW ){
-        printf("%s\n", db_column_text(&q, 0));
+        fossil_print("%s\n", db_column_text(&q, 0));
       }
       db_finalize(&q);
     }else{
       int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
                          g.argv[3]);
@@ -473,13 +473,13 @@
         " ORDER BY tagname"
       );
       while( db_step(&q)==SQLITE_ROW ){
         const char *zName = db_column_text(&q, 0);
         if( fRaw ){
-          printf("%s\n", zName);
+          fossil_print("%s\n", zName);
         }else if( strncmp(zName, "sym-", 4)==0 ){
-          printf("%s\n", &zName[4]);
+          fossil_print("%s\n", &zName[4]);
         }
       }
       db_finalize(&q);
     }else if( g.argc==4 ){
       int rid = name_to_rid(g.argv[3]);
@@ -497,13 +497,13 @@
         if( fRaw==0 ){
           if( strncmp(zName, "sym-", 4)!=0 ) continue;
           zName += 4;
         }
         if( zValue && zValue[0] ){
-          printf("%s=%s\n", zName, zValue);
+          fossil_print("%s=%s\n", zName, zValue);
         }else{
-          printf("%s\n", zName);
+          fossil_print("%s\n", zName);
         }
       }
       db_finalize(&q);
     }else{
       usage("tag list ?CHECK-IN?");

Index: src/timeline.c
==================================================================
--- src/timeline.c
+++ src/timeline.c
@@ -1203,16 +1203,16 @@
     char zPrefix[80];
     char zUuid[UUID_SIZE+1];
     
     sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId);
     if( memcmp(zDate, zPrevDate, 10) ){
-      printf("=== %.10s ===\n", zDate);
+      fossil_print("=== %.10s ===\n", zDate);
       memcpy(zPrevDate, zDate, 10);
       nLine++;
     }
     if( zCom==0 ) zCom = "";
-    printf("%.8s ", &zDate[11]);
+    fossil_print("%.8s ", &zDate[11]);
     zPrefix[0] = 0;
     if( nParent>1 ){
       sqlite3_snprintf(sizeof(zPrefix), zPrefix, "*MERGE* ");
       n = strlen(zPrefix);
     }
@@ -1453,13 +1453,13 @@
      "  FROM plink p, plink c"
      " WHERE p.cid=c.pid  AND p.mtime>c.mtime"
   );
   while( db_step(&q)==SQLITE_ROW ){
     if( !showDetail ){
-      printf("%s\n", db_column_text(&q, 1));
+      fossil_print("%s\n", db_column_text(&q, 1));
     }else{
-      printf("%.14s -> %.14s   %s -> %s\n",
+      fossil_print("%.14s -> %.14s   %s -> %s\n",
          db_column_text(&q, 0),
          db_column_text(&q, 1),
          db_column_text(&q, 2),
          db_column_text(&q, 3));
     }

Index: src/tkt.c
==================================================================
--- src/tkt.c
+++ src/tkt.c
@@ -216,11 +216,12 @@
   char *zTag = mprintf("tkt-%s", zTktUuid);
   int tagid = tag_findid(zTag, 1);
   Stmt q;
   Manifest *pTicket;
   int createFlag = 1;
-  
+
+  fossil_free(zTag);  
   db_multi_exec(
      "DELETE FROM ticket WHERE tkt_uuid=%Q", zTktUuid
   );
   db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid);
   while( db_step(&q)==SQLITE_ROW ){

Index: src/undo.c
==================================================================
--- src/undo.c
+++ src/undo.c
@@ -58,19 +58,19 @@
     if( old_exists ){
       db_ephemeral_blob(&q, 0, &new);
     }
     if( old_exists ){
       if( new_exists ){
-        printf("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname);
+        fossil_print("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname);
       }else{
-        printf("NEW %s\n", zPathname);
+        fossil_print("NEW %s\n", zPathname);
       }
       blob_write_to_file(&new, zFullname);
       file_setexe(zFullname, old_exe);
     }else{
-      printf("DELETE %s\n", zPathname);
-      unlink(zFullname);
+      fossil_print("DELETE %s\n", zPathname);
+      file_delete(zFullname);
     }
     blob_reset(&new);
     free(zFullname);
     db_finalize(&q);
     db_prepare(&q, 
@@ -297,11 +297,11 @@
 ** Complete the undo process is one is currently in process.
 */
 void undo_finish(void){
   if( undoActive ){
     if( undoNeedRollback ){
-      printf("\"fossil undo\" is available to undo changes"
+      fossil_print("\"fossil undo\" is available to undo changes"
              " to the working checkout.\n");
     }
     undoActive = 0;
     undoNeedRollback = 0;
   }
@@ -319,11 +319,11 @@
 void undo_rollback(void){
   if( !undoNeedRollback ) return;
   assert( undoActive );
   undoNeedRollback = 0;
   undoActive = 0;
-  printf("Rolling back prior filesystem changes...\n");
+  fossil_print("Rolling back prior filesystem changes...\n");
   undo_all_filesystem(0);
 }
 
 /*
 ** COMMAND: undo
@@ -360,34 +360,35 @@
   verify_all_options();
   db_begin_transaction();
   undo_available = db_lget_int("undo_available", 0);
   if( explainFlag ){
     if( undo_available==0 ){
-      printf("No undo or redo is available\n");
+      fossil_print("No undo or redo is available\n");
     }else{
       Stmt q;
       int nChng = 0;
       zCmd = undo_available==1 ? "undo" : "redo";
-      printf("A %s is available for the following command:\n\n   %s %s\n\n",
-              zCmd, g.argv[0], db_lget("undo_cmdline", "???"));
+      fossil_print("A %s is available for the following command:\n\n"
+                   "   %s %s\n\n",
+                   zCmd, g.argv[0], db_lget("undo_cmdline", "???"));
       db_prepare(&q,
         "SELECT existsflag, pathname FROM undo ORDER BY pathname"
       );
       while( db_step(&q)==SQLITE_ROW ){
         if( nChng==0 ){
-          printf("The following file changes would occur if the "
-                 "command above is %sne:\n\n", zCmd);
+          fossil_print("The following file changes would occur if the "
+                       "command above is %sne:\n\n", zCmd);
         }
         nChng++;
-        printf("%s %s\n", 
+        fossil_print("%s %s\n", 
            db_column_int(&q,0) ? "UPDATE" : "DELETE",
            db_column_text(&q, 1)
         );
       }
       db_finalize(&q);
       if( nChng==0 ){
-        printf("No file changes would occur with this undo/redo.\n");
+        fossil_print("No file changes would occur with this undo/redo.\n");
       }
     }
   }else{
     int vid1 = db_lget_int("checkout", 0);
     int vid2;
@@ -410,11 +411,11 @@
         blob_reset(&path);
       }
     }
     vid2 = db_lget_int("checkout", 0);
     if( vid1!=vid2 ){
-      printf("--------------------\n");
+      fossil_print("--------------------\n");
       show_common_info(vid2, "updated-to:", 1, 0);
     }
   }
   db_end_transaction(0);
 }

Index: src/update.c
==================================================================
--- src/update.c
+++ src/update.c
@@ -253,18 +253,18 @@
   if( debugFlag ){
     db_prepare(&q,
        "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe FROM fv"
     );
     while( db_step(&q)==SQLITE_ROW ){
-       printf("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d\n",
+       fossil_print("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d\n",
           db_column_int(&q, 0),
           db_column_int(&q, 4),
           db_column_int(&q, 5),
           db_column_int(&q, 3),
           db_column_int(&q, 6));
-       printf("     fnv = [%s]\n", db_column_text(&q, 1));
-       printf("     fnt = [%s]\n", db_column_text(&q, 2));
+       fossil_print("     fnv = [%s]\n", db_column_text(&q, 1));
+       fossil_print("     fnt = [%s]\n", db_column_text(&q, 2));
     }
     db_finalize(&q);
   }
 
   /* If FILES appear on the command-line, remove from the "fv" table
@@ -331,26 +331,26 @@
     nameChng = fossil_strcmp(zName, zNewName);
     if( idv>0 && ridv==0 && idt>0 && ridt>0 ){
       /* Conflict.  This file has been added to the current checkout
       ** but also exists in the target checkout.  Use the current version.
       */
-      printf("CONFLICT %s\n", zName);
+      fossil_print("CONFLICT %s\n", zName);
       nConflict++;
     }else if( idt>0 && idv==0 ){
       /* File added in the target. */
-      printf("ADD %s\n", zName);
+      fossil_print("ADD %s\n", zName);
       undo_save(zName);
       if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
     }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){
       /* The file is unedited.  Change it to the target version */
       undo_save(zName);
-      printf("UPDATE %s\n", zName);
+      fossil_print("UPDATE %s\n", zName);
       if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
     }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){
       /* The file missing from the local check-out. Restore it to the
       ** version that appears in the target. */
-      printf("UPDATE %s\n", zName);
+      fossil_print("UPDATE %s\n", zName);
       undo_save(zName);
       if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
     }else if( idt==0 && idv>0 ){
       if( ridv==0 ){
         /* Added in current checkout.  Continue to hold the file as
@@ -357,25 +357,26 @@
         ** as an addition */
         db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv);
       }else if( chnged ){
         /* Edited locally but deleted from the target.  Do not track the
         ** file but keep the edited version around. */
-        printf("CONFLICT %s - edited locally but deleted by update\n", zName);
+        fossil_print("CONFLICT %s - edited locally but deleted by update\n",
+                     zName);
         nConflict++;
       }else{
-        printf("REMOVE %s\n", zName);
+        fossil_print("REMOVE %s\n", zName);
         undo_save(zName);
-        if( !nochangeFlag ) unlink(zFullPath);
+        if( !nochangeFlag ) file_delete(zFullPath);
       }
     }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
       /* Merge the changes in the current tree into the target version */
       Blob r, t, v;
       int rc;
       if( nameChng ){
-        printf("MERGE %s -> %s\n", zName, zNewName);
+        fossil_print("MERGE %s -> %s\n", zName, zNewName);
       }else{
-        printf("MERGE %s\n", zName);
+        fossil_print("MERGE %s\n", zName);
       }
       undo_save(zName);
       content_get(ridt, &t);
       content_get(ridv, &v);
       rc = merge_3way(&v, zFullPath, &t, &r);
@@ -383,51 +384,51 @@
         if( !nochangeFlag ){
           blob_write_to_file(&r, zFullNewPath);
           file_setexe(zFullNewPath, isexe);
         }
         if( rc>0 ){
-          printf("***** %d merge conflicts in %s\n", rc, zNewName);
+          fossil_print("***** %d merge conflicts in %s\n", rc, zNewName);
           nConflict++;
         }
       }else{
         if( !nochangeFlag ){
           blob_write_to_file(&t, zFullNewPath);
           file_setexe(zFullNewPath, isexe);
         }
-        printf("***** Cannot merge binary file %s\n", zNewName);
+        fossil_print("***** Cannot merge binary file %s\n", zNewName);
         nConflict++;
       }
-      if( nameChng && !nochangeFlag ) unlink(zFullPath);
+      if( nameChng && !nochangeFlag ) file_delete(zFullPath);
       blob_reset(&v);
       blob_reset(&t);
       blob_reset(&r);
     }else{
       if( chnged ){
-        if( verboseFlag ) printf("EDITED %s\n", zName);
+        if( verboseFlag ) fossil_print("EDITED %s\n", zName);
       }else{
         db_bind_int(&mtimeXfer, ":idv", idv);
         db_bind_int(&mtimeXfer, ":idt", idt);
         db_step(&mtimeXfer);
         db_reset(&mtimeXfer);
-        if( verboseFlag ) printf("UNCHANGED %s\n", zName);
+        if( verboseFlag ) fossil_print("UNCHANGED %s\n", zName);
       }
     }
     free(zFullPath);
     free(zFullNewPath);
   }
   db_finalize(&q);
   db_finalize(&mtimeXfer);
-  printf("--------------\n");
+  fossil_print("--------------\n");
   show_common_info(tid, "updated-to:", 1, 0);
 
   /* Report on conflicts
   */
   if( nConflict && !nochangeFlag ){
     if( internalUpdate ){
       internalConflictCnt = nConflict;
     }else{
-      printf("WARNING: %d merge conflicts - see messages above for details.\n",
+      fossil_print("WARNING: %d merge conflicts - see messages above for details.\n",
               nConflict);
     }
   }
   
   /*
@@ -570,23 +571,23 @@
     zFile = db_column_text(&q, 0);
     zFull = mprintf("%/%/", g.zLocalRoot, zFile);
     errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2);
     if( errCode==2 ){
       if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){
-        printf("UNMANAGE: %s\n", zFile);
+        fossil_print("UNMANAGE: %s\n", zFile);
       }else{
         undo_save(zFile);
-        unlink(zFull);
-        printf("DELETE: %s\n", zFile);
+        file_delete(zFull);
+        fossil_print("DELETE: %s\n", zFile);
       }
       db_multi_exec("DELETE FROM vfile WHERE pathname=%Q", zFile);
     }else{
       sqlite3_int64 mtime;
       undo_save(zFile);
       blob_write_to_file(&record, zFull);
       file_setexe(zFull, isExe);
-      printf("REVERTED: %s\n", zFile);
+      fossil_print("REVERTED: %s\n", zFile);
       mtime = file_mtime(zFull);
       db_multi_exec(
          "UPDATE vfile"
          "   SET mtime=%lld, chnged=0, deleted=0, isexe=%d, mrid=rid,"
          "       pathname=coalesce(origname,pathname), origname=NULL"     

Index: src/url.c
==================================================================
--- src/url.c
+++ src/url.c
@@ -208,26 +208,26 @@
   if( g.argc!=3 && g.argc!=4 ){
     usage("URL");
   }
   url_parse(g.argv[2]);
   for(i=0; i<2; i++){
-    printf("g.urlIsFile    = %d\n", g.urlIsFile);
-    printf("g.urlIsHttps   = %d\n", g.urlIsHttps);
-    printf("g.urlIsSsh     = %d\n", g.urlIsSsh);
-    printf("g.urlProtocol  = %s\n", g.urlProtocol);
-    printf("g.urlName      = %s\n", g.urlName);
-    printf("g.urlPort      = %d\n", g.urlPort);
-    printf("g.urlDfltPort  = %d\n", g.urlDfltPort);
-    printf("g.urlHostname  = %s\n", g.urlHostname);
-    printf("g.urlPath      = %s\n", g.urlPath);
-    printf("g.urlUser      = %s\n", g.urlUser);
-    printf("g.urlPasswd    = %s\n", g.urlPasswd);
-    printf("g.urlCanonical = %s\n", g.urlCanonical);
-    printf("g.urlFossil    = %s\n", g.urlFossil);
+    fossil_print("g.urlIsFile    = %d\n", g.urlIsFile);
+    fossil_print("g.urlIsHttps   = %d\n", g.urlIsHttps);
+    fossil_print("g.urlIsSsh     = %d\n", g.urlIsSsh);
+    fossil_print("g.urlProtocol  = %s\n", g.urlProtocol);
+    fossil_print("g.urlName      = %s\n", g.urlName);
+    fossil_print("g.urlPort      = %d\n", g.urlPort);
+    fossil_print("g.urlDfltPort  = %d\n", g.urlDfltPort);
+    fossil_print("g.urlHostname  = %s\n", g.urlHostname);
+    fossil_print("g.urlPath      = %s\n", g.urlPath);
+    fossil_print("g.urlUser      = %s\n", g.urlUser);
+    fossil_print("g.urlPasswd    = %s\n", g.urlPasswd);
+    fossil_print("g.urlCanonical = %s\n", g.urlCanonical);
+    fossil_print("g.urlFossil    = %s\n", g.urlFossil);
     if( g.urlIsFile || g.urlIsSsh ) break;
     if( i==0 ){
-      printf("********\n");
+      fossil_print("********\n");
       url_enable_proxy("Using proxy: ");
     }
   }
 }
 
@@ -276,11 +276,11 @@
     char *zOriginalUser = g.urlUser;
     char *zOriginalPasswd = g.urlPasswd;
     g.urlUser = 0;
     g.urlPasswd = "";
     url_parse(zProxy);
-    if( zMsg ) printf("%s%s\n", zMsg, g.urlCanonical);
+    if( zMsg ) fossil_print("%s%s\n", zMsg, g.urlCanonical);
     g.urlPath = zOriginalUrl;
     g.urlHostname = zOriginalHost;
     if( g.urlUser ){
       char *zCredentials1 = mprintf("%s:%s", g.urlUser, g.urlPasswd);
       char *zCredentials2 = encode64(zCredentials1, -1);

Index: src/user.c
==================================================================
--- src/user.c
+++ src/user.c
@@ -117,11 +117,11 @@
     prompt_for_passphrase(zPrompt, pPassphrase);
     if( verify==0 ) break;
     if( verify==1 && blob_size(pPassphrase)==0 ) break;
     prompt_for_passphrase("Retype new password: ", &secondTry);
     if( blob_compare(pPassphrase, &secondTry) ){
-      printf("Passphrases do not match.  Try again...\n");
+      fossil_print("Passphrases do not match.  Try again...\n");
     }else{
       break;
     }
   }
   blob_reset(&secondTry);
@@ -132,11 +132,11 @@
 */
 void prompt_user(const char *zPrompt, Blob *pIn){
   char *z;
   char zLine[1000];
   blob_zero(pIn);
-  printf("%s", zPrompt);
+  fossil_print("%s", zPrompt);
   fflush(stdout);
   z = fgets(zLine, sizeof(zLine), stdin);
   if( z ){
     strip_string(pIn, z);
   }
@@ -212,11 +212,11 @@
     );
     free(zPw);
   }else if( n>=2 && strncmp(g.argv[2],"default",n)==0 ){
     user_select();
     if( g.argc==3 ){
-      printf("%s\n", g.zLogin);
+      fossil_print("%s\n", g.zLogin);
     }else{
       if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.argv[3]) ){
         fossil_fatal("no such user: %s", g.argv[3]);
       }
       if( g.localOpen ){
@@ -227,11 +227,11 @@
     }
   }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){
     Stmt q;
     db_prepare(&q, "SELECT login, info FROM user ORDER BY login");
     while( db_step(&q)==SQLITE_ROW ){
-      printf("%-12s %s\n", db_column_text(&q, 0), db_column_text(&q, 1));
+      fossil_print("%-12s %s\n", db_column_text(&q, 0), db_column_text(&q, 1));
     }
     db_finalize(&q);
   }else if( n>=2 && strncmp(g.argv[2],"password",2)==0 ){
     char *zPrompt;
     int uid;
@@ -246,11 +246,11 @@
     }else{
       zPrompt = mprintf("New password for %s: ", g.argv[3]);
       prompt_for_password(zPrompt, &pw, 1);
     }
     if( blob_size(&pw)==0 ){
-      printf("password unchanged\n");
+      fossil_print("password unchanged\n");
     }else{
       char *zSecret = sha1_shared_secret(blob_str(&pw), g.argv[3], 0);
       db_multi_exec("UPDATE user SET pw=%Q, mtime=now() WHERE uid=%d",
                     zSecret, uid);
       free(zSecret);
@@ -268,11 +268,11 @@
       db_multi_exec(
         "UPDATE user SET cap=%Q, mtime=now() WHERE uid=%d",
         g.argv[4], uid
       );
     }
-    printf("%s\n", db_text(0, "SELECT cap FROM user WHERE uid=%d", uid));
+    fossil_print("%s\n", db_text(0, "SELECT cap FROM user WHERE uid=%d", uid));
   }else{
     fossil_panic("user subcommand should be one of: "
                  "capabilities default list new password");
   }
 }

Index: src/vfile.c
==================================================================
--- src/vfile.c
+++ src/vfile.c
@@ -264,11 +264,11 @@
       if( cReply=='n' || cReply=='N' ){
         blob_reset(&content);
         continue;
       }
     }
-    if( verbose ) printf("%s\n", &zName[nRepos]);
+    if( verbose ) fossil_print("%s\n", &zName[nRepos]);
     blob_write_to_file(&content, zName);
     file_setexe(zName, isExe);
     blob_reset(&content);
     db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
                   file_mtime(zName), id);
@@ -286,11 +286,11 @@
                  " WHERE vid=%d AND mrid>0", g.zLocalRoot, vid);
   while( db_step(&q)==SQLITE_ROW ){
     const char *zName;
 
     zName = db_column_text(&q, 0);
-    unlink(zName);
+    file_delete(zName);
   }
   db_finalize(&q);
   db_multi_exec("UPDATE vfile SET mtime=NULL WHERE vid=%d AND mrid>0", vid);
 }
 
@@ -428,11 +428,11 @@
     const char *zName = db_column_text(&q, 1);
     int isSelected = db_column_int(&q, 3);
 
     if( isSelected ){
       md5sum_step_text(zName, -1);
-      in = fopen(zFullpath,"rb");
+      in = fossil_fopen(zFullpath,"rb");
       if( in==0 ){
         md5sum_step_text(" 0\n", -1);
         continue;
       }
       fseek(in, 0L, SEEK_END);
@@ -491,26 +491,27 @@
     int rid = db_column_int(&q, 2);
 
     blob_zero(&disk);
     rc = blob_read_from_file(&disk, zFullpath);
     if( rc<0 ){
-      printf("ERROR: cannot read file [%s]\n", zFullpath);
+      fossil_print("ERROR: cannot read file [%s]\n", zFullpath);
       blob_reset(&disk);
       continue;
     }
     blob_zero(&repo);
     content_get(rid, &repo);
     if( blob_size(&repo)!=blob_size(&disk) ){
-      printf("ERROR: [%s] is %d bytes on disk but %d in the repository\n",
+      fossil_print("ERROR: [%s] is %d bytes on disk but %d in the repository\n",
              zName, blob_size(&disk), blob_size(&repo));
       blob_reset(&disk);
       blob_reset(&repo);
       continue;
     }
     if( blob_compare(&repo, &disk) ){
-      printf("ERROR: [%s] is different on disk compared to the repository\n",
-             zName);
+      fossil_print(
+          "ERROR: [%s] is different on disk compared to the repository\n",
+          zName);
     }
     blob_reset(&disk);
     blob_reset(&repo);
   }
   db_finalize(&q);

Index: src/wiki.c
==================================================================
--- src/wiki.c
+++ src/wiki.c
@@ -916,20 +916,20 @@
       FILE * zF;
       short doClose = 0;
       if( (1 == strlen(zFile)) && ('-'==zFile[0]) ){
         zF = stdout;
       }else{
-        zF = fopen( zFile, "w" );
+        zF = fossil_fopen( zFile, "w" );
         doClose = zF ? 1 : 0;
       }
       if( ! zF ){
         fossil_fatal("wiki export could not open output file for writing.");
       }
       fprintf(zF,"%.*s\n", i, zBody);
       if( doClose ) fclose(zF);
     }else{
-      printf("%.*s\n", i, zBody);
+      fossil_print("%.*s\n", i, zBody);
     }
     manifest_destroy(pWiki);
     return;
   }else
   if( strncmp(g.argv[2],"commit",n)==0
@@ -945,14 +945,14 @@
     }else{
       blob_read_from_file(&content, g.argv[4]);
     }
     if( g.argv[2][1]=='r' ){
       wiki_cmd_commit(zPageName, 1, &content);
-      printf("Created new wiki page %s.\n", zPageName);
+      fossil_print("Created new wiki page %s.\n", zPageName);
     }else{
       wiki_cmd_commit(zPageName, 0, &content);
-      printf("Updated wiki page %s.\n", zPageName);
+      fossil_print("Updated wiki page %s.\n", zPageName);
     }
     blob_reset(&content);
   }else
   if( strncmp(g.argv[2],"delete",n)==0 ){
     if( g.argc!=5 ){
@@ -966,11 +966,11 @@
       "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'"
       " ORDER BY lower(tagname) /*sort*/"
     );
     while( db_step(&q)==SQLITE_ROW ){
       const char *zName = db_column_text(&q, 0);
-      printf( "%s\n",zName);
+      fossil_print( "%s\n",zName);
     }
     db_finalize(&q);
   }else
   {
     goto wiki_cmd_usage;

Index: src/wikiformat.c
==================================================================
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1734,6 +1734,7 @@
         break;
       }
     }
     z += n;
   }
+  free(renderer.aStack);
 }

Index: src/winhttp.c
==================================================================
--- src/winhttp.c
+++ src/winhttp.c
@@ -92,11 +92,11 @@
       wanted = find_content_length(zHdr) + (&z[4]-zHdr) - amt;
       break;
     }
   }
   if( amt>=sizeof(zHdr) ) goto end_request;
-  out = fopen(zRequestFName, "wb");
+  out = fossil_fopen(zRequestFName, "wb");
   if( out==0 ) goto end_request;
   fwrite(zHdr, 1, amt, out);
   while( wanted>0 ){
     got = recv(p->s, zHdr, sizeof(zHdr), 0);
     if( got==SOCKET_ERROR ) goto end_request;
@@ -112,11 +112,11 @@
   sqlite3_snprintf(sizeof(zCmd), zCmd, "\"%s\" http \"%s\" %s %s %s --nossl%s",
     fossil_nameofexe(), g.zRepositoryName, zRequestFName, zReplyFName, 
     inet_ntoa(p->addr.sin_addr), p->zOptions
   );
   fossil_system(zCmd);
-  in = fopen(zReplyFName, "rb");
+  in = fossil_fopen(zReplyFName, "rb");
   if( in ){
     while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
       send(p->s, zHdr, got, 0);
     }
   }
@@ -123,12 +123,12 @@
 
 end_request:
   if( out ) fclose(out);
   if( in ) fclose(in);
   closesocket(p->s);
-  unlink(zRequestFName);
-  unlink(zReplyFName);
+  file_delete(zRequestFName);
+  file_delete(zReplyFName);
   free(p);
 }
 
 /*
 ** Start a listening socket and process incoming HTTP requests on
@@ -146,11 +146,11 @@
   SOCKADDR_IN addr;
   int idCnt = 0;
   int iPort = mnPort;
   Blob options;
 
-  if( zStopper ) unlink(zStopper);
+  if( zStopper ) file_delete(zStopper);
   blob_zero(&options);
   if( zNotFound ){
     blob_appendf(&options, " --notfound %s", zNotFound);
   }
   if( g.useLocalauth ){
@@ -190,17 +190,17 @@
       fossil_fatal("unable to open listening socket on any"
                    " port in the range %d..%d", mnPort, mxPort);
     }
   }
   zTempPrefix = mprintf("fossil_server_P%d_", iPort);
-  printf("Listening for HTTP requests on TCP port %d\n", iPort);
+  fossil_print("Listening for HTTP requests on TCP port %d\n", iPort);
   if( zBrowser ){
     zBrowser = mprintf(zBrowser, iPort);
-    printf("Launch webbrowser: %s\n", zBrowser);
+    fossil_print("Launch webbrowser: %s\n", zBrowser);
     fossil_system(zBrowser);
   }
-  printf("Type Ctrl-C to stop the HTTP server\n");
+  fossil_print("Type Ctrl-C to stop the HTTP server\n");
   for(;;){
     SOCKET client;
     SOCKADDR_IN client_addr;
     HttpRequest *p;
     int len = sizeof(client_addr);

Index: src/xfer.c
==================================================================
--- src/xfer.c
+++ src/xfer.c
@@ -1206,11 +1206,11 @@
   }
   blob_zero(&g.cgiIn);
   blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]);
   disableLogin = 1;
   page_xfer();
-  printf("%s\n", cgi_extract_content(&notUsed));
+  fossil_print("%s\n", cgi_extract_content(&notUsed));
 }
 
 /*
 ** Format strings for progress reporting.
 */
@@ -1390,11 +1390,11 @@
     xfer.nFileSent = 0;
     xfer.nDeltaSent = 0;
     xfer.nGimmeSent = 0;
     xfer.nIGotSent = 0;
     if( !g.cgiOutput && !g.fQuiet ){
-      printf("waiting for server...");
+      fossil_print("waiting for server...");
     }
     fflush(stdout);
     if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){
       nErr++;
       break;
@@ -1446,11 +1446,11 @@
       xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
       nCardRcvd++;
       if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){
         pctDone = (recv.iCursor*100)/recv.nUsed;
         if( pctDone!=lastPctDone ){
-          printf("\rprocessed: %d%%         ", pctDone);
+          fossil_print("\rprocessed: %d%%         ", pctDone);
           lastPctDone = pctDone;
           fflush(stdout);
         }
       }