diff --git a/ChangeLog b/ChangeLog
index 77b0b19768c3817659ad1f3db5bc5be06b49709a..f39f845eb0a794b762c478d5a71044b55a664e44 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -142,6 +142,13 @@ CVS code -
 	  warnings or errors.  Changes to cancel_fork(),
 	  handle_hipterm(), do_suspend(), and do_cont(). (David
 	  Benbennick)
+	- Change flags to an unsigned long, and totsize to a size_t.
+	  (DLR)
+	- Store the number of multibyte characters instead of the number
+	  of single-byte characters in totsize, and use get_totals() to
+	  get the value of totsize in a few more places.  Changes to
+	  read_line(), read_file(), do_delete(), do_input(),
+	  get_totals(), and do_cursorpos(). (DLR)
 - cut.c:
   do_cut_text()
 	- If keep_cutbuffer is FALSE, only blow away the text in the
diff --git a/src/files.c b/src/files.c
index 0df6c8fda1ed8d28896bd29454e1e5688727411f..7c3321f109e152e06e1a1a2540bed9be167be262 100644
--- a/src/files.c
+++ b/src/files.c
@@ -80,10 +80,8 @@ filestruct *read_line(char *buf, filestruct *prev, bool *first_line_ins,
 #ifndef NANO_SMALL
     /* If it's a DOS file (CR LF), and file conversion isn't disabled,
      * strip out the CR part. */
-    if (!ISSET(NO_CONVERT) && len > 0 && buf[len - 1] == '\r') {
+    if (!ISSET(NO_CONVERT) && len > 0 && buf[len - 1] == '\r')
 	fileptr->data[len - 1] = '\0';
-	totsize--;
-    }
 #endif
 
     if (*first_line_ins || fileage == NULL) {
@@ -131,6 +129,8 @@ void read_file(FILE *f, const char *filename)
 {
     size_t num_lines = 0;
 	/* The number of lines in the file. */
+    size_t num_chars = 0;
+	/* The number of bytes in the file. */
     size_t len = 0;
 	/* The length of the current line of the file. */
     size_t i = 0;
@@ -220,7 +220,6 @@ void read_file(FILE *f, const char *filename)
 	    len = 1;
 
 	    num_lines++;
-	    totsize++;
 	    buf[0] = input;
 	    buf[1] = '\0';
 	    i = 1;
@@ -238,11 +237,11 @@ void read_file(FILE *f, const char *filename)
 		bufx += 128;
 		buf = charealloc(buf, bufx);
 	    }
+
 	    buf[i] = input;
 	    buf[i + 1] = '\0';
 	    i++;
 	}
-	totsize++;
     }
 
     /* This conditional duplicates previous read_byte() behavior.
@@ -255,9 +254,10 @@ void read_file(FILE *f, const char *filename)
     /* If file conversion isn't disabled and the last character in this
      * file is a CR, read it in properly as a Mac format line. */
     if (len == 0 && !ISSET(NO_CONVERT) && input == '\r') {
+	len = 1;
+
 	buf[0] = input;
 	buf[1] = '\0';
-	len = 1;
     }
 #endif
 
@@ -276,13 +276,13 @@ void read_file(FILE *f, const char *filename)
 	/* Read in the last line properly. */
 	fileptr = read_line(buf, fileptr, &first_line_ins, len);
 	num_lines++;
-	totsize++;
     }
+
     free(buf);
 
     /* If we didn't get a file and we don't already have one, make a new
      * file. */
-    if (totsize == 0 || fileptr == NULL)
+    if (fileptr == NULL)
 	new_file();
 
     /* Did we try to insert a file of 0 bytes? */
@@ -296,10 +296,12 @@ void read_file(FILE *f, const char *filename)
 	} else if (fileptr->next == NULL) {
 	    filebot = fileptr;
 	    new_magicline();
-	    totsize--;
 	}
     }
 
+    get_totals(fileage, filebot, NULL, &num_chars);
+    totsize += num_chars;
+
 #ifndef NANO_SMALL
     if (format == 3)
 	statusbar(
@@ -319,7 +321,7 @@ void read_file(FILE *f, const char *filename)
     } else
 #endif
 	statusbar(P_("Read %lu line", "Read %lu lines",
-		(unsigned long)num_lines),(unsigned long)num_lines);
+		(unsigned long)num_lines), (unsigned long)num_lines);
 
     totlines += num_lines;
 }
@@ -337,6 +339,7 @@ int open_file(const char *filename, bool newfie, FILE **f)
     struct stat fileinfo;
 
     assert(f != NULL);
+
     if (filename == NULL || filename[0] == '\0' ||
 	    stat(filename, &fileinfo) == -1) {
 	if (newfie) {
@@ -708,6 +711,7 @@ void splice_opennode(openfilestruct *begin, openfilestruct *newnode,
 	openfilestruct *end)
 {
     assert(newnode != NULL && begin != NULL);
+
     newnode->next = end;
     newnode->prev = begin;
     begin->next = newnode;
@@ -719,6 +723,7 @@ void splice_opennode(openfilestruct *begin, openfilestruct *newnode,
 void unlink_opennode(openfilestruct *fileptr)
 {
     assert(fileptr != NULL && fileptr->prev != NULL && fileptr->next != NULL && fileptr != fileptr->prev && fileptr != fileptr->next);
+
     fileptr->prev->next = fileptr->next;
     fileptr->next->prev = fileptr->prev;
     delete_opennode(fileptr);
@@ -728,6 +733,7 @@ void unlink_opennode(openfilestruct *fileptr)
 void delete_opennode(openfilestruct *fileptr)
 {
     assert(fileptr != NULL && fileptr->filename != NULL && fileptr->fileage != NULL);
+
     free(fileptr->filename);
     free_filestruct(fileptr->fileage);
     free(fileptr);
@@ -739,6 +745,7 @@ void delete_opennode(openfilestruct *fileptr)
 void free_openfilestruct(openfilestruct *src)
 {
     assert(src != NULL);
+
     while (src != src->next) {
 	src = src->next;
 	delete_opennode(src->prev);
diff --git a/src/global.c b/src/global.c
index 1e3751fb791fe5ecbdc38a000fa55b6fcf5cf72e..b714c74470fc6afec54e1cc4b32036567e9a9afc 100644
--- a/src/global.c
+++ b/src/global.c
@@ -40,7 +40,7 @@ char *last_search = NULL;	/* Last string we searched for */
 char *last_replace = NULL;	/* Last replacement string */
 int search_last_line;		/* Is this the last search line? */
 
-long flags = 0;			/* Our flag containing many options */
+unsigned long flags = 0;	/* Our flag containing many options */
 WINDOW *topwin;			/* Top buffer */
 WINDOW *edit;			/* The file portion of the editor */
 WINDOW *bottomwin;		/* Bottom buffer */
@@ -103,7 +103,8 @@ char *backup_dir = NULL;	/* Backup directory. */
 
 char *answer = NULL;		/* Answer str to many questions */
 int totlines = 0;		/* Total number of lines in the file */
-long totsize = 0;		/* Total number of bytes in the file */
+size_t totsize = 0;		/* Total number of characters in the
+				   file */
 size_t placewewant = 0;		/* The column we'd like the cursor
 				   to jump to when we go to the
 				   next or previous line */
diff --git a/src/nano.c b/src/nano.c
index 5c83b2facf411cf23eb36464f21f638ae1b02eb4..568aa845769475a8de97a248e140e9f328eb10b2 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -701,7 +701,7 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
 	filestruct *top, size_t top_x, filestruct *bot, size_t bot_x)
 {
     filestruct *top_save;
-    long part_totsize;
+    size_t part_totsize;
     bool at_edittop;
 #ifndef NANO_SMALL
     bool mark_inside = FALSE;
@@ -800,7 +800,7 @@ void copy_from_filestruct(filestruct *file_top, filestruct *file_bot)
 {
     filestruct *top_save;
     int part_totlines;
-    long part_totsize;
+    size_t part_totsize;
     bool at_edittop;
 
     assert(file_top != NULL && file_bot != NULL);
@@ -1214,7 +1214,7 @@ void do_delete(void)
 	if (current_x < mark_beginx && mark_beginbuf == current)
 	    mark_beginx -= char_buf_len;
 #endif
-	totsize -= char_buf_len;
+	totsize--;
     } else if (current != filebot && (current->next != filebot ||
 	current->data[0] == '\0')) {
 	/* We can delete the line before filebot only if it is blank: it
@@ -2099,7 +2099,7 @@ const char *do_alt_speller(char *tempfile_name)
 	 * the alternate spell command.  The line that mark_beginbuf
 	 * points to will be freed, so we save the line number and
 	 * restore afterwards. */
-    long old_totsize = totsize;
+    size_t totsize_save = totsize;
 	/* Our saved value of totsize, used when we spell-check a marked
 	 * selection. */
 
@@ -2161,7 +2161,7 @@ const char *do_alt_speller(char *tempfile_name)
 
 #ifndef NANO_SMALL
     if (old_mark_set) {
-	long part_totsize;
+	size_t part_totsize;
 
 	/* If the mark was on, partition the filestruct so that it
 	 * contains only the marked text, and keep track of whether the
@@ -2176,7 +2176,7 @@ const char *do_alt_speller(char *tempfile_name)
 	 * it from the saved value of totsize.  Note that we don't need
 	 * to save totlines. */
 	get_totals(top, bot, NULL, &part_totsize);
-	old_totsize -= part_totsize;
+	totsize_save -= part_totsize;
     }
 #endif
 
@@ -2225,8 +2225,8 @@ const char *do_alt_speller(char *tempfile_name)
 	 * saved value the actual value. */
 	renumber(top_save);
 	totlines = filebot->lineno;
-	old_totsize += totsize;
-	totsize = old_totsize;
+	totsize_save += totsize;
+	totsize = totsize_save;
 
 	/* Assign mark_beginbuf to the line where the mark began
 	 * before. */
@@ -2842,7 +2842,8 @@ void do_justify(bool full_justify)
      * unjustifies.  Note that we don't need to save totlines. */
     size_t current_x_save = current_x;
     int current_y_save = current_y;
-    long flags_save = flags, totsize_save = totsize;
+    unsigned long flags_save = flags;
+    size_t totsize_save = totsize;
     filestruct *edittop_save = edittop, *current_save = current;
 #ifndef NANO_SMALL
     filestruct *mark_beginbuf_save = mark_beginbuf;
@@ -3770,7 +3771,7 @@ void do_output(char *output, size_t output_len)
 		current_len - current_x + char_buf_len);
 	charcpy(&current->data[current_x], char_buf, char_buf_len);
 	current_len += char_buf_len;
-	totsize += char_buf_len;
+	totsize++;
 	set_modified();
 
 #ifndef NANO_SMALL
@@ -4104,7 +4105,7 @@ int main(int argc, char **argv)
 	char *alt_speller_cpy = alt_speller;
 #endif
 	ssize_t tabsize_cpy = tabsize;
-	long flags_cpy = flags;
+	unsigned long flags_cpy = flags;
 
 #ifndef DISABLE_OPERATINGDIR
 	operating_dir = NULL;
diff --git a/src/nano.h b/src/nano.h
index 345839a6be406910bf6d39cae90ac8805606555d..51457f33a0b683dadde02e88a3a8de729173cdf7 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -172,8 +172,8 @@ typedef struct openfilestruct {
     size_t placewewant;		/* Current file's place we want. */
     int totlines;		/* Current file's total number of
 				 * lines. */
-    long totsize;		/* Current file's total size. */
-    long flags;			/* Current file's flags: modification
+    size_t totsize;		/* Current file's total size. */
+    unsigned long flags;	/* Current file's flags: modification
 				 * status (and marking status, if
 				 * available). */
     file_format fmt;		/* Current file's format. */
diff --git a/src/proto.h b/src/proto.h
index 605396ecdb0ddad082ad6bfee41243dad2100047..145e381ba73df7bb17a9c105a9e6e9dea67fb5ec 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -39,8 +39,8 @@ extern size_t placewewant;
 #ifndef NANO_SMALL
 extern size_t mark_beginx;
 #endif
-extern long totsize;
-extern long flags;
+extern size_t totsize;
+extern unsigned long flags;
 extern ssize_t tabsize;
 extern int currslen;
 
@@ -559,7 +559,7 @@ void mark_order(const filestruct **top, size_t *top_x, const filestruct
 	**bot, size_t *bot_x, bool *right_side_up);
 #endif
 void get_totals(const filestruct *begin, const filestruct *end, int
-	*lines, long *size);
+	*lines, size_t *size);
 #ifndef DISABLE_TABCOMP
 int check_wildcard_match(const char *text, const char *pattern);
 #endif
diff --git a/src/search.c b/src/search.c
index 6f657810de52d741ce6f9a0e5a78016bdabb5c09..e83edc39c6441e954b4e99a400a871e7a3151763 100644
--- a/src/search.c
+++ b/src/search.c
@@ -1044,7 +1044,7 @@ void do_find_bracket(void)
     char regexp_pat[] = "[  ]";
     size_t current_x_save, pww_save;
     int count = 1;
-    long flags_save;
+    unsigned long flags_save;
     filestruct *current_save;
 
     ch_under_cursor = current->data[current_x];
diff --git a/src/utils.c b/src/utils.c
index 64064098e84679f8636d5ed99a0bce217b488a0f..b0a3301935daec5146011f16f8502706856859df 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -373,7 +373,7 @@ void mark_order(const filestruct **top, size_t *top_x, const filestruct
 /* Calculate the number of lines and the number of characters between
  * begin and end, and return them in lines and size, respectively. */
 void get_totals(const filestruct *begin, const filestruct *end, int
-	*lines, long *size)
+	*lines, size_t *size)
 {
     const filestruct *f;
 
@@ -390,7 +390,7 @@ void get_totals(const filestruct *begin, const filestruct *end, int
 
 	/* Count the number of characters on this line. */
 	if (size != NULL) {
-	    *size += strlen(f->data);
+	    *size += mbstrlen(f->data);
 
 	    /* Count the newline if we have one. */
 	    if (f->next != NULL)
@@ -406,7 +406,7 @@ void get_totals(const filestruct *begin, const filestruct *end, int
 
 	/* Count the number of characters on this line. */
 	if (size != NULL) {
-	    *size += strlen(f->data);
+	    *size += mbstrlen(f->data);
 
 	    /* Count the newline if we have one. */
 	    if (f->next != NULL)
diff --git a/src/winio.c b/src/winio.c
index ee4284cfab3fd175d25775bb3b5a821bfc14201d..0d5ce0a54f916f81b0d12c922927ff1a29308eb2 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -3784,21 +3784,23 @@ void display_main_list(void)
  * alone, but next time we will display. */
 void do_cursorpos(bool constant)
 {
-    const filestruct *fileptr;
+    char c;
+    filestruct *f;
     size_t i = 0;
-    static size_t old_i = 0;
-    static long old_totsize = -1;
+    static size_t old_i = 0, old_totsize = (size_t)-1;
 
     assert(current != NULL && fileage != NULL && totlines != 0);
 
-    if (old_totsize == -1)
+    if (old_totsize == (size_t)-1)
 	old_totsize = totsize;
 
-    for (fileptr = fileage; fileptr != current; fileptr = fileptr->next) {
-	assert(fileptr != NULL);
-	i += strlen(fileptr->data) + 1;
-    }
-    i += current_x;
+    c = current->data[current_x];
+    f = current->next;
+    current->data[current_x] = '\0';
+    current->next = NULL;
+    get_totals(fileage, current, NULL, &i);
+    current->data[current_x] = c;
+    current->next = f;
 
     /* Check whether totsize is correct.  Else there is a bug
      * somewhere. */
@@ -3819,13 +3821,13 @@ void do_cursorpos(bool constant)
 	size_t cur_len = strlenpt(current->data) + 1;
 	int linepct = 100 * current->lineno / totlines;
 	int colpct = 100 * xpt / cur_len;
-	int bytepct = totsize == 0 ? 0 : 100 * i / totsize;
+	int bytepct = (totsize == 0) ? 0 : 100 * i / totsize;
 
 	statusbar(
 	    _("line %ld/%ld (%d%%), col %lu/%lu (%d%%), char %lu/%ld (%d%%)"),
 		    current->lineno, totlines, linepct,
 		    (unsigned long)xpt, (unsigned long)cur_len, colpct,
-		    (unsigned long)i, totsize, bytepct);
+		    (unsigned long)i, (unsigned long)totsize, bytepct);
 	UNSET(DISABLE_CURPOS);
     }