]> git.sur5r.net Git - bacula/bacula/commitdiff
- Add first cut of UTF-8 support to conio. It seems to be working
authorKern Sibbald <kern@sibbald.com>
Wed, 8 Sep 2004 21:18:59 +0000 (21:18 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 8 Sep 2004 21:18:59 +0000 (21:18 +0000)
  pretty well. Moving by words will definitely not work though.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1590 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/kernstodo
bacula/src/console/conio.c

index 09b22fd96c79d526a4a8f3779eaab76c861d98c7..89f2f18b7ce4bd335b980f115b0dd5a295c6af80 100644 (file)
@@ -1,5 +1,5 @@
                     Kern's ToDo List
-                   07 Septermber 2004
+                   08 Septermber 2004
 
 Major development:      
 Project                     Developer
@@ -20,6 +20,9 @@ Version 1.35                Kern (see below)
   you lost/broke the Catalog -- do the same for "I know my
   file is there how do I get it back?".
 
+- Add "Multiple connections = yes/no" to catalog resource.
+- Add "Rerun failed levels = yes/no" to Job resource.
+
    
 Maybe for 1.35:
 - Look at patches/bacula_db.b2z postgresql that loops during restore.
@@ -128,8 +131,8 @@ Wish list:
 - Minimal autochanger handling in Bacula and in btape.
 - Look into how tar does not save sockets and the possiblity of
   not saving them in Bacula (Martin Simmons reported this).
-  The next two lines will show them.
-  localmounts=`awk '/ext/ { print $2 }' /proc/mounts`   # or whatever
+- Add All Local Partitions = yes to new style saves.
+- localmounts=`awk '/ext/ { print $2 }' /proc/mounts`   # or whatever
   find $localmounts -xdev -type s -ls
 - Fix restore jobs so that multiple jobs can run if they
   are not using the same tape(s).
@@ -188,14 +191,12 @@ Wish list:
 - look at mxt-changer.html
 - Make ? do a help command (no return needed).
 - Implement restore directory.
-- Add All Local Partitions = yes to new style saves.
 - Document streams and how to implement them.
 - Possibly implement "Ensure Full Backup = yes" looks for a failed full backup
   and upgrades the current backup if one exists.
 - Check that barcode reading and update slots scan works.
 - Try not to re-backup a file if a new hard link is added.
 - Add feature to backup hard links only, but not the data.
-- Add "All Local = yes" option to save to include all local partitions.
 - Fix stream handling to be simpler.
 - Add Priority and Bootstrap to Run a Job.
 - Eliminate Restore "Run Restore Job" prompt by allowing new "run command
@@ -207,13 +208,8 @@ Wish list:
 - Add display of total selected files to Restore window.
 - Add tree pane to left of window.
 - Add progress meter.
-- Polling does not work for restore. It tries a number of times,
-  gives up, and crashes the SD.
-- Lock jcr_chain when doing attach/detach in acquire.c
-- Add assert in free_jcr if attach/detach chain active.
 - Max wait time or max run time causes seg fault -- see runtime-bug.txt
 - Document writing to a CD/DVD with Bacula.
-- Add check for tape alerts.
 - Add a "base" package to the window installer for pthreadsVCE.dll
   which is needed by all packages.
 - Add message to user to check for fixed block size when the forward
@@ -223,14 +219,10 @@ Wish list:
 - Possibly implement: Action = Unmount Device="TapeDrive1" in Admin jobs.
 - Setup lrrd graphs: (http://www.linpro.no/projects/lrrd/) Mike Acar.
 - Revisit the question of multiple Volumes (disk) on a single device.
-- Finish SIGHUP work.
-- Check that all change in wait status in the SD are        
-  signaled to the Director.
 - Add a block copy option to bcopy.
 - Investigate adding Mac Resource Forks.
 - Finish work on Gnome restore GUI.
 - Fix "llist jobid=xx" where no fileset or client exists.
-- Check pruning of restore jobs.
 - From Chris Hull:
    it seems to be complaining about 12:00pm which should be a valid 12
    hour time.  I changed the time to 11:59am and everything works fine.
@@ -243,26 +235,14 @@ Wish list:
   then list last 20 backups.
 - Add all pools in Dir conf to DB also update them to catch changed
   LabelFormats and such.
-- Update volumes FromPool=xxx does all volumes.
 - Pass Director resource name as an option to the Console.
 - Add a "batch" mode to the Console (no unsolicited queries, ...).
-- Add code to check for tape alerts -- tapeinfo.
-- Make sure list of Volumes needed is in correct order for restore.
-  See havana.
-- Remove paths (and files that reference them) that have no trailing slash   
-  in dbcheck -- or add a trailing slash.
-- Remove Filenames (and files that reference them) that have a trailing
-  slash in dbcheck -- or remove the trailing slash.
-- Remove orphaned paths/filenames by copying them to a new table with a 
-  reference count, then mark all referenced files/paths and remove unreferenced
-  ones.
 - Add a .list all files in the restore tree (probably also a list all files)
   Do both a long and short form.
 - Allow browsing the catalog to see all versions of a file (with 
   stat data on each file).
 - Restore attributes of directory if replace=never set but directory
   did not exist.
-- Allow "delete job jobid=xxx,yyy,aaa-bbb" i.e. list + ranges.
 - Use SHA1 on authentication if possible.
 - See comtest-xxx.zip for Windows code to talk to USB.
 - Make btape accept Device Names in addition to Archive names.
@@ -283,40 +263,23 @@ Wish list:
 - Add disk seeking on restore.  - Allow
    for optional cancelling of SD and FD in case DIR
   gets a fatal error. Requested by Jesse Guardiani <jesse@wingnet.net>
-- Bizarre message: Error: Could not open WriteBootstrap file:
-- Build console in client only build.
 - Add "limit=n" for "list jobs"
 - Check new HAVE_WIN32 open bits.    
 - Check if the tape has moved before writing.  
 - Handling removable disks -- see below:
-- Multiple drive autochanger support -- see below.
 - Keep track of tape use time, and report when cleaning is necessary.
-- Fix FreeBSD mt_count problem.
 - Add FromClient and ToClient keywords on restore command (or
   BackupClient RestoreClient).
-- Automatic "update slots" on user configuration directive when a
-  slot error occurs.
 - Implement a JobSet, which groups any number of jobs. If the
   JobSet is started, all the jobs are started together.
   Allow Pool, Level, and Schedule overrides.
 - Enhance cancel to timeout BSOCK packets after a specific delay.
-- When I restore to Windows the Created, Accessed and Modifiedtimes are
-  those of the time of the restore, not those of the originalfile.  
-  The dates you will find in your restore log seem to be the original
-   creation dates
-- Volume "add"ed to Pool gets recycled in first use. VolBytes=0
-- If a tape is recycled while it is mounted, Stanislav Tvrudy must do an
-  additional mount to deblock the job.
-- From Johan Decock:
-  bscan: sql_update.c:65 UPDATE File SET MD5='Ij+5kwN6TFIxK+8l8+/I+A' WHERE FileId=0
-  bscan: bscan.c:1074 Could not add MD5/SHA1 to File record. ERR=sql_update.c:65 Update problem: affected_rows=0
 - Do scheduling by UTC using gmtime_r() in run_conf, scheduler, and   
   ua_status.!!! Thanks to Alan Brown for this tip.
 - Look at updating Volume Jobs so that Max Volume Jobs = 1 will work
   correctly for multiple simultaneous jobs.
 - Correct code so that FileSet MD5 is calculated for < and | filename   
   generation.
-- Mark Volume in error on error from WEOF.
 - Implement the Media record flag that indicates that the Volume does disk 
   addressing.
 - Implement VolAddr, which is used when Volume is addressed like a disk,
@@ -327,8 +290,6 @@ Wish list:
 - Fix fast block rejection (stored/read_record.c:118). It passes a null
   pointer (rec) to try_repositioning().
 - Look at extracting Win data from BackupRead.
-- Having dashes in filenames apparently creates problems for restore
-  by filename??? hard to believe.
 - Implement RestoreJobRetention? Maybe better "JobRetention" in a Job,
   which would take precidence over the Catalog "JobRetention".
 - Implement Label Format in Add and Label console commands.
@@ -340,7 +301,6 @@ Wish list:
   resources, like Level? If so, I think I'd make it an optional directive
   in Job, Client, and Pool, with precedence such that Job overrides Client
   which in turn overrides Pool.
-- Print a message when a job starts if the conf file is not current.
 
 - Spooling ideas taken from Volker Sauer's and other's emails:
    > IMHO job spooling should be turned on
@@ -439,20 +399,10 @@ Ideas from Jerry Scharf:
         even more important, it's not flaky
         it has an open access catalog, opening many possibilities
         it's pushing toward heterogeneous systems capability
-  simple things:
-        I don't remember an include file directive for config files
-                (not filesets, actual config directives)
-        can you check the configs without starting the daemon?
-        some warnings about possible common mistakes
   big things:
-   doing the testing and blessing of concurrent backup writes
-        this is absolutely necessary in the enterprise
-   easy user recovery GUI with full access checking
    Macintosh file client
         macs are an interesting niche, but I fear a server is a rathole
    working bare iron recovery for windows
-   much better handling on running config changes
-        thinking through the logic of what happens to jobs in progress
    the option for  inc/diff backups not reset on fileset revision
         a) use both change and inode update time against base time
         b) do the full catalog check (expensive but accurate)
@@ -505,9 +455,7 @@ Ideas from Jerry Scharf:
   to the user, who would then use "mount" as described above 
   once he had actually inserted the disk.
 - Implement dump/print label to UA
-- Implement disk spooling. Two parts: 1. Spool to disk then
-  immediately to tape to speed up tape operations. 2. Spool to
-  disk only when the tape is full, then when a tape is hung move
+- Spool to disk only when the tape is full, then when a tape is hung move
   it to tape.
 - Scratch Pool where the volumes can be re-assigned to any Pool.
 - bextract is sending everything to the log file ****FIXME****
@@ -824,12 +772,8 @@ Ideas from Jerry Scharf:
   if full status requested or if some level of debug on.
 - Make database type selectable by .conf files i.e. at runtime
 - Set flag for uname -a.  Add to Volume label.
-- Implement throttled work queue.
 - Restore files modified after date
 - SET LD_RUN_PATH=$HOME/mysql/lib/mysql
-- Implement Restore FileSet=
-- Create a protocol.h and protocol.c where all protocol messages
-  are concentrated.
 - Remove duplicate fields from jcr (e.g. jcr.level and jcr.jr.Level, ...).
 - Timout a job or terminate if link goes down, or reopen link and query.
 - Concept of precious tapes (cannot be reused).
index 372310b69215d346f4e9d95cd0bddc9365e0e711..9b866c317a6222d54e751291a97eaad7a7fa7a36 100755 (executable)
 
  */
 
+/* 
+ * UTF-8
+ *  If the top bit of a UTF-8 string is 0 (8 bits), then it
+ *    is a normal ASCII character.
+ *  If the top two bits are 11 (i.e. (c & 0xC0) == 0xC0 then
+ *    it is the start of a series of chars (up to 5)
+ *  Each subsequent character starts with 10 (i.e. (c & 0xC0) == 0x80)
+ */
+
 
 #ifdef TEST_PROGRAM
 #include <stdio.h>
@@ -192,11 +201,12 @@ static short char_map[600]= {
 
 /* Function Prototypes */
 
-static int input_char(void);
-static int t_gnc(void);
+static unsigned int input_char(void);
+static unsigned int t_gnc(void);
 static void insert_space(char *curline, int line_len);
-static void forward(int i, char *str, int str_len);
-static void backup(int i);
+static void insert_hole(char *curline, int line_len);
+static void forward(char *str, int str_len);
+static void backup(char *curline);
 static void delchr(int cnt, char *curline, int line_len);
 static int iswordc(char c);
 static int  next_word(char *ldb_buf);
@@ -210,7 +220,7 @@ static void t_honk_horn(void);
 static void t_insert_line(void);
 static void t_delete_line(void);
 static void t_clrline(int pos, int width);
-void t_sendl(char *msg, int len);
+void t_sendl(const char *msg, int len);
 void t_send(char *msg);
 void t_char(char c);
 static void asclrs();
@@ -218,7 +228,7 @@ static void ascurs(int y, int x);
 
 static void rawmode(FILE *input);
 static void normode(void);
-static int t_getch();
+static unsigned t_getch();
 static void asclrl(int pos, int width);
 static void asinsl();
 static void asdell();
@@ -295,22 +305,23 @@ char *bstrncpy(char *dest, const char *src, int maxlen)
 /*
  * New style string mapping to function code
  */
-static int do_smap(int c)
+static unsigned do_smap(unsigned c)
 {
     char str[MAX_STAB];
     int len = 0; 
     stab_t *tstab;
     int i, found;
+    unsigned cm;
 
     len = 1;
     str[0] = c;
     str[1] = 0;
 
-    if (c != 27) {
-       c = char_map[c];
-    }
-    if (c <= 0) {
+    cm = char_map[c];
+    if (cm == 0) {
        return c;
+    } else {
+       c = cm;
     }
     for ( ;; ) {
        found = 0;
@@ -397,10 +408,10 @@ static void add_smap(char *str, int func)
 
 /* Get the next character from the terminal - performs table lookup on
    the character to do the desired translation */
-static int
+static unsigned int
 input_char()
 {
-    int c;
+    unsigned c;
 
     if ((c=t_gnc()) <= 599) {        /* IBM generates codes up to 260 */
          c = do_smap(c);
@@ -428,7 +439,9 @@ input_line(char *string, int length)
 {
    char curline[2000];               /* edit buffer */
    int noline;
-   int c;
+   unsigned c;
+   int more;
+   int i;
 
     if (first) {
        poolinit();                  /* build line pool */
@@ -440,7 +453,7 @@ input_line(char *string, int length)
          clrbrk();
          break;
        }
-       switch (c=(int)input_char()) {
+       switch (c=input_char()) {
        case F_RETURN:               /* CR */
            t_sendl("\r\n", 2);       /* yes, print it and */
           goto done;                /* get out */
@@ -469,13 +482,13 @@ input_line(char *string, int length)
           delchr(1, curline, sizeof(curline));       /* delete one character */
           break;
        case F_CSRLFT:               /* Backspace */
-          backup(1);
+          backup(curline);
           break;
        case F_CSRRGT:
-          forward(1,curline, sizeof(curline));
+          forward(curline, sizeof(curline));
           break;
        case F_ERSCHR:               /* Rubout */
-          backup(1);
+          backup(curline);
           delchr(1, curline, sizeof(curline));
           break;
        case F_DELEOL:
@@ -484,10 +497,16 @@ input_line(char *string, int length)
               cl = cp;
           break;
        case F_NXTWRD:
-          forward(next_word(curline),curline, sizeof(curline));
+          i = next_word(curline);
+          while (i--) {
+             forward(curline, sizeof(curline));
+          }
           break;
        case F_PRVWRD:
-          backup(prev_word(curline));
+          i = prev_word(curline);
+          while (i--) {
+             backup(curline);
+          }
           break;
        case F_DELWRD:
           delchr(next_word(curline), curline, sizeof(curline)); /* delete word */
@@ -500,20 +519,24 @@ input_line(char *string, int length)
           /* Note fall through */
        case F_DELLIN:
        case F_ERSLIN:
-          backup(cp);               /* backup to beginning of line */
+          while (cp > 0) {
+             backup(curline);      /* backup to beginning of line */
+          }
           t_clrline(0,t_width);     /* erase line */
           cp = 0;
           cl = 0;                   /* reset cursor counter */
           break;
        case F_SOL:
-          backup(cp);
+          while (cp > 0) {
+             backup(curline);
+          }
           break;
        case F_EOL:
           while (cp < cl) {
-              forward(1,curline, sizeof(curline));
+              forward(curline, sizeof(curline));
           }
           while (cp > cl) {
-              backup(1);
+              backup(curline);
           }
           break;
        case F_TINS:                 /* toggle insert mode */
@@ -527,13 +550,35 @@ input_line(char *string, int length)
               }
               t_honk_horn();        /* complain */
           } else {
+              if ((c & 0xC0) == 0xC0) {
+                 if ((c & 0xFC) == 0xFC) {
+                    more = 5;
+                 } else if ((c & 0xF8) == 0xF8) {
+                    more = 4;
+                 } else if ((c & 0xF0) == 0xF0) {
+                    more = 3;
+                 } else if ((c & 0xE0) == 0xE0) {
+                    more = 2;
+                 } else {
+                    more = 1;
+                 }
+              } else {
+                 more = 0;
+              }
               if (mode_insert) {
                  insert_space(curline, sizeof(curline));
               }
               curline[cp++] = c;    /* store character in line being built */
-              t_char((char)c);      /* echo character to terminal */
+              t_char(c);      /* echo character to terminal */
+              while (more--) {
+                 c= input_char();  
+                 insert_hole(curline, sizeof(curline));
+                 curline[cp++] = c;    /* store character in line being built */
+                 t_char(c);      /* echo character to terminal */
+              }
               if (cp > cl) {
                  cl = cp;           /* keep current length */
+                 curline[cp] = 0;
               }
           }
           break;
@@ -555,60 +600,121 @@ insert_space(char *curline, int curline_len)
 {
    int i;
 
-   if (cp > cl || cl+1 > curline_len) return;
+   if (cp > cl || cl+1 > curline_len) {
+      return;
+   }
    /* Note! source and destination overlap */
    memmove(&curline[cp+1],&curline[cp],i=cl-cp);
    cl++;
-   i++;
    curline[cp] = ' ';
-   forward(i,curline, curline_len);
-   backup(i);
+   i = 0;
+   while (cl > cp) {
+      forward(curline, curline_len);
+      i++;
+   }
+   while (i--) {
+      backup(curline);
+   }
+}
+
+
+static void
+insert_hole(char *curline, int curline_len)
+{
+   int i;
+
+   if (cp > cl || cl+1 > curline_len) {
+      return;
+   }
+   /* Note! source and destination overlap */
+   memmove(&curline[cp+1], &curline[cp], i=cl-cp);
+   cl++;
+   curline[cl] = 0;
 }
 
 
 /* Move cursor forward keeping characters under it */
 static void
-forward(int i, char *str, int str_len)
+forward(char *str, int str_len)
 {
-   while (i--) {
-      if (cp > str_len) {
-        return;
-      }
-      if (cp>=cl) {
-          t_char(' ');
-          str[cp+1] = ' ';
-      } else {
-         t_char(str[cp]);
+   if (cp > str_len) {
+      return;
+   }
+   if (cp >= cl) {
+       t_char(' ');
+       str[cp+1] = ' ';
+       str[cp+2] = 0;
+   } else {
+       t_char(str[cp]);
+       if ((str[cp] & 0xC0) == 0xC0) {
+         cp++;
+         while ((str[cp] & 0xC0) == 0x80) {
+            t_char(str[cp]);
+            cp++;
+         }
+         cp--;
+       }
+   }
+   cp++;
+}
+
+/* How many characters under the cursor */
+static int 
+char_count(int cptr, char *str)
+{
+   int cnt = 1;
+   if (cptr > cl) {
+      return 0;
+   }
+   if ((str[cptr] & 0xC0) == 0xC0) {
+      cptr++;
+      while ((str[cptr] & 0xC0) == 0x80) {
+        cnt++;
+        cptr++;
       }
-      cp++;
    }
+   return cnt;
 }
 
 /* Backup cursor keeping characters under it */
 static void
-backup(int i)
+backup(char *str) 
 {
-    for ( ; i && cp; i--,cp--) {
-       t_char('\010');
+    if (cp == 0) {
+       return;
+    }
+    while ((str[cp] & 0xC0) == 0x80) {
+       cp--;
     }
+    t_char('\010');
+    cp--;
 }
 
 /* Delete the character under the cursor */
 static void
-delchr(int cnt, char *curline, int line_len) 
+delchr(int del, char *curline, int line_len) 
 {
-   register int i;
+   int i, cnt;
 
-   if (cp > cl)
+   if (cp > cl || del == 0) {
       return;
-   if ((i=cl-cp-cnt+1) > 0) {
-      memcpy(&curline[cp], &curline[cp+cnt],i);
    }
-   curline[cl -= cnt] = EOS;
-   t_clrline(0,t_width);
-   if (cl > cp) {
-      forward(i=cl-cp,curline, line_len);
-      backup(i);
+   while (del-- && cp > 0) {
+      cnt = char_count(cp, curline);
+      if ((i=cl-cp-cnt) > 0) {
+        memcpy(&curline[cp], &curline[cp+cnt], i);
+      }
+      cl -= cnt;
+      curline[cl] = EOS;
+      t_clrline(0, t_width);
+      i = 0;
+      while (cl > cp) {
+        forward(curline, line_len);
+        i++;
+      }
+      while (i--) {
+        backup(curline);
+      }
    }
 }
 
@@ -619,9 +725,9 @@ iswordc(char c)
    if (mode_wspace)
       return !isspace(c);
    if (c >= '0' && c <= '9')
-      return TRUE;
+      return true;
    if (c == '$' || c == '%')
-      return TRUE;
+      return true;
    return isalpha(c);
 }
 
@@ -668,10 +774,12 @@ prev_word(char *ldb_buf)
 static void
 prtcur(char *str)
 {
-    backup(cp);
+    while (cp > 0) {
+       backup(str);
+    }
     t_clrline(0,t_width);
     cp = cl = strlen(str);
-    t_sendl(str,cl);
+    t_sendl(str, cl);
 }
 
 
@@ -920,7 +1028,7 @@ static void normode()
 }
 
 /* Get next character from terminal/script file/unget buffer */
-static int
+static unsigned
 t_gnc()
 {
     return t_getch();
@@ -928,19 +1036,19 @@ t_gnc()
 
 
 /* Get next character from OS */
-static int t_getch(void)
+static unsigned t_getch(void)
 {
-   char c;
+   unsigned char c;
 
    if (read(0, &c, 1) != 1) {
       c = 0;
    }
-   return (int)c;   
+   return (unsigned)c;  
 }
     
 /* Send message to terminal - primitive routine */
 void
-t_sendl(char *msg, int len)
+t_sendl(const char *msg, int len)
 {
    write(1, msg, len);
 }