summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2009-07-14 13:57:45 +0000
committerNils Wallménius <nils@rockbox.org>2009-07-14 13:57:45 +0000
commit3d4701a6e41616cf581a297bab1451cf2db70249 (patch)
treef845837c96ffbed7d59ddf8308f3b3e7c40cb8c9
parentc2900a1bacd5d98b57a0d15ea2add1bc08764057 (diff)
downloadrockbox-3d4701a6e41616cf581a297bab1451cf2db70249.tar.gz
rockbox-3d4701a6e41616cf581a297bab1451cf2db70249.zip
FS#10080
* Move strncpy() from core to the pluginlib * Introduce strlcpy() and use that instead in most places (use memcpy in a few) in core and some plugins * Drop strncpy() from the codec api as no codec used it * Bump codec and plugin api versions git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21863 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/bookmark.c7
-rw-r--r--apps/buffering.c4
-rw-r--r--apps/codecs.c1
-rw-r--r--apps/codecs.h5
-rw-r--r--apps/cuesheet.c13
-rw-r--r--apps/debug_menu.c3
-rw-r--r--apps/gui/buttonbar.c9
-rw-r--r--apps/gui/gwps-common.c11
-rw-r--r--apps/gui/option_select.c6
-rw-r--r--apps/gui/statusbar.c7
-rw-r--r--apps/gui/wps_parser.c9
-rw-r--r--apps/iap.c13
-rw-r--r--apps/menu.c2
-rw-r--r--apps/menus/main_menu.c2
-rw-r--r--apps/metadata.c2
-rw-r--r--apps/metadata/metadata_common.c5
-rw-r--r--apps/metadata/mp3.c5
-rw-r--r--apps/misc.c4
-rw-r--r--apps/mpeg.c6
-rw-r--r--apps/onplay.c14
-rw-r--r--apps/playback.c2
-rw-r--r--apps/playlist.c21
-rw-r--r--apps/playlist_catalog.c6
-rw-r--r--apps/plugin.c2
-rw-r--r--apps/plugin.h7
-rw-r--r--apps/plugins/chessbox/chessbox_pgn.c2
-rw-r--r--apps/plugins/dict.c3
-rw-r--r--apps/plugins/doom/rockmacros.h1
-rw-r--r--apps/plugins/goban/sgf_output.c2
-rw-r--r--apps/plugins/invadrox.c2
-rw-r--r--apps/plugins/keybox.c18
-rw-r--r--apps/plugins/lib/SOURCES1
-rw-r--r--apps/plugins/lib/configfile.c2
-rw-r--r--apps/plugins/lib/highscore.c5
-rw-r--r--apps/plugins/lib/strncpy.c (renamed from firmware/common/strncpy.c)0
-rw-r--r--apps/plugins/lib/wrappers.h2
-rw-r--r--apps/plugins/lua/lobject.c3
-rw-r--r--apps/plugins/lua/lstrlib.c4
-rw-r--r--apps/plugins/lua/rockconf.h2
-rw-r--r--apps/plugins/mp3_encoder.c5
-rw-r--r--apps/plugins/mpegplayer/mpeg_settings.c2
-rw-r--r--apps/plugins/pictureflow/pictureflow.c5
-rw-r--r--apps/plugins/properties.c30
-rw-r--r--apps/plugins/random_folder_advance_config.c10
-rw-r--r--apps/plugins/rockboy/menu.c10
-rw-r--r--apps/plugins/rockboy/rockmacros.h2
-rw-r--r--apps/plugins/rockpaint.c2
-rw-r--r--apps/plugins/shortcuts/shortcuts_common.c8
-rw-r--r--apps/plugins/sokoban.c11
-rw-r--r--apps/plugins/splitedit.c4
-rw-r--r--apps/plugins/sudoku/sudoku.c8
-rw-r--r--apps/plugins/test_codec.c3
-rw-r--r--apps/plugins/text_editor.c2
-rw-r--r--apps/plugins/zxbox/snapshot.c6
-rw-r--r--apps/plugins/zxbox/spconf.c3
-rw-r--r--apps/plugins/zxbox/sptape.c3
-rw-r--r--apps/plugins/zxbox/tapefile.c6
-rw-r--r--apps/recorder/albumart.c5
-rw-r--r--apps/recorder/pcm_record.c8
-rw-r--r--apps/recorder/radio.c5
-rw-r--r--apps/recorder/recording.c2
-rw-r--r--apps/replaygain.c3
-rw-r--r--apps/root_menu.c4
-rw-r--r--apps/settings.c34
-rw-r--r--apps/settings_list.c2
-rw-r--r--apps/tagcache.c2
-rw-r--r--apps/tagtree.c17
-rw-r--r--apps/talk.c4
-rw-r--r--apps/tree.c4
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/common/dir_uncached.c11
-rw-r--r--firmware/common/dircache.c28
-rw-r--r--firmware/common/file.c3
-rw-r--r--firmware/common/strlcpy.c52
-rw-r--r--firmware/drivers/fat.c4
-rw-r--r--firmware/drivers/lcd-16bit.c2
-rw-r--r--firmware/drivers/lcd-1bit-vert.c2
-rw-r--r--firmware/drivers/lcd-2bit-vert.c2
-rw-r--r--firmware/drivers/lcd-2bit-vi.c2
-rw-r--r--firmware/drivers/lcd-charcell.c2
-rw-r--r--firmware/general.c4
-rw-r--r--firmware/include/string.h3
-rw-r--r--firmware/logf.c2
83 files changed, 271 insertions, 271 deletions
diff --git a/apps/bookmark.c b/apps/bookmark.c
index 8c3cc48391..892a3d35b2 100644
--- a/apps/bookmark.c
+++ b/apps/bookmark.c
@@ -1002,17 +1002,14 @@ static bool parse_bookmark(const char *bookmark,
1002 if (resume_file != NULL) 1002 if (resume_file != NULL)
1003 { 1003 {
1004 size_t len = (end == NULL) ? strlen(s) : (size_t) (end - s); 1004 size_t len = (end == NULL) ? strlen(s) : (size_t) (end - s);
1005
1006 len = MIN(resume_file_size - 1, len); 1005 len = MIN(resume_file_size - 1, len);
1007 strncpy(resume_file, s, len); 1006 strlcpy(resume_file, s, len + 1);
1008 resume_file[len] = 0;
1009 } 1007 }
1010 1008
1011 if (end != NULL && file_name != NULL) 1009 if (end != NULL && file_name != NULL)
1012 { 1010 {
1013 end++; 1011 end++;
1014 strncpy(file_name, end, MAX_PATH - 1); 1012 strlcpy(file_name, end, MAX_PATH);
1015 file_name[MAX_PATH - 1] = 0;
1016 } 1013 }
1017 1014
1018 return true; 1015 return true;
diff --git a/apps/buffering.c b/apps/buffering.c
index afc444a456..08590c9fdf 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -919,7 +919,7 @@ int bufopen(const char *file, size_t offset, enum data_type type)
919 h->widx = buf_widx; 919 h->widx = buf_widx;
920 h->available = 0; 920 h->available = 0;
921 h->type = type; 921 h->type = type;
922 strncpy(h->path, file, MAX_PATH); 922 strlcpy(h->path, file, MAX_PATH);
923 923
924 buf_widx += sizeof(struct mp3entry); /* safe because the handle 924 buf_widx += sizeof(struct mp3entry); /* safe because the handle
925 can't wrap */ 925 can't wrap */
@@ -952,7 +952,7 @@ int bufopen(const char *file, size_t offset, enum data_type type)
952 return ERR_BUFFER_FULL; 952 return ERR_BUFFER_FULL;
953 } 953 }
954 954
955 strncpy(h->path, file, MAX_PATH); 955 strlcpy(h->path, file, MAX_PATH);
956 h->offset = adjusted_offset; 956 h->offset = adjusted_offset;
957 h->ridx = buf_widx; 957 h->ridx = buf_widx;
958 h->widx = buf_widx; 958 h->widx = buf_widx;
diff --git a/apps/codecs.c b/apps/codecs.c
index c86aeda422..0a3dde64be 100644
--- a/apps/codecs.c
+++ b/apps/codecs.c
@@ -122,7 +122,6 @@ struct codec_api ci = {
122 122
123 /* strings and memory */ 123 /* strings and memory */
124 strcpy, 124 strcpy,
125 strncpy,
126 strlen, 125 strlen,
127 strcmp, 126 strcmp,
128 strcat, 127 strcat,
diff --git a/apps/codecs.h b/apps/codecs.h
index 631cf58a77..b61c3c0c94 100644
--- a/apps/codecs.h
+++ b/apps/codecs.h
@@ -75,12 +75,12 @@
75#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */ 75#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
76 76
77/* increase this every time the api struct changes */ 77/* increase this every time the api struct changes */
78#define CODEC_API_VERSION 32 78#define CODEC_API_VERSION 33
79 79
80/* update this to latest version if a change to the api struct breaks 80/* update this to latest version if a change to the api struct breaks
81 backwards compatibility (and please take the opportunity to sort in any 81 backwards compatibility (and please take the opportunity to sort in any
82 new function which are "waiting" at the end of the function table) */ 82 new function which are "waiting" at the end of the function table) */
83#define CODEC_MIN_API_VERSION 32 83#define CODEC_MIN_API_VERSION 33
84 84
85/* codec return codes */ 85/* codec return codes */
86enum codec_status { 86enum codec_status {
@@ -180,7 +180,6 @@ struct codec_api {
180 180
181 /* strings and memory */ 181 /* strings and memory */
182 char* (*strcpy)(char *dst, const char *src); 182 char* (*strcpy)(char *dst, const char *src);
183 char* (*strncpy)(char *dst, const char *src, size_t length);
184 size_t (*strlen)(const char *str); 183 size_t (*strlen)(const char *str);
185 int (*strcmp)(const char *, const char *); 184 int (*strcmp)(const char *, const char *);
186 char *(*strcat)(char *s1, const char *s2); 185 char *(*strcat)(char *s1, const char *s2);
diff --git a/apps/cuesheet.c b/apps/cuesheet.c
index aace64a8fc..fa1d93f334 100644
--- a/apps/cuesheet.c
+++ b/apps/cuesheet.c
@@ -84,7 +84,7 @@ bool look_for_cuesheet_file(const char *trackpath, char *found_cue_path)
84 return false; 84 return false;
85 } 85 }
86 86
87 strncpy(cuepath, trackpath, MAX_PATH); 87 strlcpy(cuepath, trackpath, MAX_PATH);
88 dot = strrchr(cuepath, '.'); 88 dot = strrchr(cuepath, '.');
89 strcpy(dot, ".cue"); 89 strcpy(dot, ".cue");
90 90
@@ -103,7 +103,7 @@ bool look_for_cuesheet_file(const char *trackpath, char *found_cue_path)
103 } 103 }
104 104
105 if (found_cue_path) 105 if (found_cue_path)
106 strncpy(found_cue_path, cuepath, MAX_PATH); 106 strlcpy(found_cue_path, cuepath, MAX_PATH);
107 return true; 107 return true;
108} 108}
109 109
@@ -205,8 +205,7 @@ bool parse_cuesheet(char *file, struct cuesheet *cue)
205 } 205 }
206 else 206 else
207 { 207 {
208 strncpy(dest, string, MAX_NAME*3); 208 strlcpy(dest, string, MAX_NAME*3 + 1);
209 dest[MAX_NAME*3] = '\0';
210 } 209 }
211 } 210 }
212 } 211 }
@@ -218,10 +217,10 @@ bool parse_cuesheet(char *file, struct cuesheet *cue)
218 for (i = 0; i < cue->track_count; i++) 217 for (i = 0; i < cue->track_count; i++)
219 { 218 {
220 if (*(cue->tracks[i].performer) == '\0') 219 if (*(cue->tracks[i].performer) == '\0')
221 strncpy(cue->tracks[i].performer, cue->performer, MAX_NAME*3); 220 strlcpy(cue->tracks[i].performer, cue->performer, MAX_NAME*3);
222 221
223 if (*(cue->tracks[i].songwriter) == '\0') 222 if (*(cue->tracks[i].songwriter) == '\0')
224 strncpy(cue->tracks[i].songwriter, cue->songwriter, MAX_NAME*3); 223 strlcpy(cue->tracks[i].songwriter, cue->songwriter, MAX_NAME*3);
225 } 224 }
226 225
227 return true; 226 return true;
@@ -271,7 +270,7 @@ static char *list_get_name_cb(int selected_item,
271 struct cuesheet *cue = (struct cuesheet *)data; 270 struct cuesheet *cue = (struct cuesheet *)data;
272 271
273 if (selected_item & 1) 272 if (selected_item & 1)
274 strncpy(buffer, cue->tracks[selected_item/2].title, buffer_len); 273 strlcpy(buffer, cue->tracks[selected_item/2].title, buffer_len);
275 else 274 else
276 snprintf(buffer, buffer_len, "%02d. %s", selected_item/2+1, 275 snprintf(buffer, buffer_len, "%02d. %s", selected_item/2+1,
277 cue->tracks[selected_item/2].performer); 276 cue->tracks[selected_item/2].performer);
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 60594b677c..648a7e6cae 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -1910,8 +1910,7 @@ static int disk_callback(int btn, struct gui_synclist *lists)
1910 1910
1911 if (card->initialized > 0) 1911 if (card->initialized > 0)
1912 { 1912 {
1913 card_name[6] = '\0'; 1913 strlcpy(card_name, ((unsigned char*)card->cid) + 3, sizeof(card_name));
1914 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1915 simplelist_addline(SIMPLELIST_ADD_LINE, 1914 simplelist_addline(SIMPLELIST_ADD_LINE,
1916 "%s Rev %d.%d", card_name, 1915 "%s Rev %d.%d", card_name,
1917 (int) card_extract_bits(card->cid, 55, 4), 1916 (int) card_extract_bits(card->cid, 55, 4),
diff --git a/apps/gui/buttonbar.c b/apps/gui/buttonbar.c
index abf1800bb2..3c343f09ac 100644
--- a/apps/gui/buttonbar.c
+++ b/apps/gui/buttonbar.c
@@ -86,18 +86,15 @@ void gui_buttonbar_set(struct gui_buttonbar * buttonbar,
86 gui_buttonbar_unset(buttonbar); 86 gui_buttonbar_unset(buttonbar);
87 if(caption1) 87 if(caption1)
88 { 88 {
89 strncpy(buttonbar->caption[0], caption1, 7); 89 strlcpy(buttonbar->caption[0], caption1, BUTTONBAR_CAPTION_LENGTH);
90 buttonbar->caption[0][7] = 0;
91 } 90 }
92 if(caption2) 91 if(caption2)
93 { 92 {
94 strncpy(buttonbar->caption[1], caption2, 7); 93 strlcpy(buttonbar->caption[1], caption2, BUTTONBAR_CAPTION_LENGTH);
95 buttonbar->caption[1][7] = 0;
96 } 94 }
97 if(caption3) 95 if(caption3)
98 { 96 {
99 strncpy(buttonbar->caption[2], caption3, 7); 97 strlcpy(buttonbar->caption[2], caption3, BUTTONBAR_CAPTION_LENGTH);
100 buttonbar->caption[2][7] = 0;
101 } 98 }
102} 99}
103 100
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index f480f616a2..c0923a9ab5 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -659,8 +659,7 @@ static char* get_dir(char* buf, int buf_size, const char* path, int level)
659 return NULL; 659 return NULL;
660 660
661 len = MIN(last_sep - sep, buf_size - 1); 661 len = MIN(last_sep - sep, buf_size - 1);
662 strncpy(buf, sep + 1, len); 662 strlcpy(buf, sep + 1, len + 1);
663 buf[len] = 0;
664 return buf; 663 return buf;
665} 664}
666 665
@@ -1183,12 +1182,12 @@ static const char *get_token_value(struct gui_wps *gwps,
1183 { 1182 {
1184 /* we need 11 characters (full line) for 1183 /* we need 11 characters (full line) for
1185 progress-bar */ 1184 progress-bar */
1186 strncpy(buf, " ", buf_size); 1185 strlcpy(buf, " ", buf_size);
1187 } 1186 }
1188 else 1187 else
1189 { 1188 {
1190 /* Tell the user if we have an OldPlayer */ 1189 /* Tell the user if we have an OldPlayer */
1191 strncpy(buf, " <Old LCD> ", buf_size); 1190 strlcpy(buf, " <Old LCD> ", buf_size);
1192 } 1191 }
1193 return buf; 1192 return buf;
1194#endif 1193#endif
@@ -1254,11 +1253,11 @@ static const char *get_token_value(struct gui_wps *gwps,
1254 break; 1253 break;
1255 case 2: 1254 case 2:
1256 case 4: 1255 case 4:
1257 strncpy(buf, id3->track_gain_string, buf_size); 1256 strlcpy(buf, id3->track_gain_string, buf_size);
1258 break; 1257 break;
1259 case 3: 1258 case 3:
1260 case 5: 1259 case 5:
1261 strncpy(buf, id3->album_gain_string, buf_size); 1260 strlcpy(buf, id3->album_gain_string, buf_size);
1262 break; 1261 break;
1263 } 1262 }
1264 return buf; 1263 return buf;
diff --git a/apps/gui/option_select.c b/apps/gui/option_select.c
index 7b6c489bf3..01259c4136 100644
--- a/apps/gui/option_select.c
+++ b/apps/gui/option_select.c
@@ -76,7 +76,7 @@ char *option_get_valuestring(const struct settings_list *setting,
76 if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) 76 if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING)
77 { 77 {
78 bool val = (bool)temp_var; 78 bool val = (bool)temp_var;
79 strncpy(buffer, str(val? setting->bool_setting->lang_yes : 79 strlcpy(buffer, str(val? setting->bool_setting->lang_yes :
80 setting->bool_setting->lang_no), buf_len); 80 setting->bool_setting->lang_no), buf_len);
81 } 81 }
82#if 0 /* probably dont need this one */ 82#if 0 /* probably dont need this one */
@@ -137,7 +137,7 @@ char *option_get_valuestring(const struct settings_list *setting,
137 const struct choice_setting *info = setting->choice_setting; 137 const struct choice_setting *info = setting->choice_setting;
138 if (info->talks[(int)temp_var] < LANG_LAST_INDEX_IN_ARRAY) 138 if (info->talks[(int)temp_var] < LANG_LAST_INDEX_IN_ARRAY)
139 { 139 {
140 strncpy(buffer, str(info->talks[(int)temp_var]), buf_len); 140 strlcpy(buffer, str(info->talks[(int)temp_var]), buf_len);
141 } 141 }
142 else 142 else
143 { 143 {
@@ -149,7 +149,7 @@ char *option_get_valuestring(const struct settings_list *setting,
149 { 149 {
150 int value= (int)temp_var; 150 int value= (int)temp_var;
151 char *val = P2STR(setting->choice_setting->desc[value]); 151 char *val = P2STR(setting->choice_setting->desc[value]);
152 strncpy(buffer, val, buf_len); 152 strlcpy(buffer, val, buf_len);
153 } 153 }
154 } 154 }
155 return buffer; 155 return buffer;
diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c
index 47dcb4ead1..5e215090f5 100644
--- a/apps/gui/statusbar.c
+++ b/apps/gui/statusbar.c
@@ -617,7 +617,7 @@ static void gui_statusbar_time(struct screen * display, struct tm *time)
617 snprintf(buffer, sizeof(buffer), "%02d:%02d", hour, minute); 617 snprintf(buffer, sizeof(buffer), "%02d:%02d", hour, minute);
618 } 618 }
619 else { 619 else {
620 strncpy(buffer, "--:--", sizeof buffer); 620 strlcpy(buffer, "--:--", sizeof(buffer));
621 } 621 }
622 display->setfont(FONT_SYSFIXED); 622 display->setfont(FONT_SYSFIXED);
623 display->getstringsize(buffer, &width, &height); 623 display->getstringsize(buffer, &width, &height);
@@ -626,7 +626,6 @@ static void gui_statusbar_time(struct screen * display, struct tm *time)
626 STATUSBAR_Y_POS, buffer); 626 STATUSBAR_Y_POS, buffer);
627 } 627 }
628 display->setfont(FONT_UI); 628 display->setfont(FONT_UI);
629
630} 629}
631#endif 630#endif
632 631
@@ -758,14 +757,14 @@ static void gui_statusbar_icon_recording_info(struct screen * display)
758 if (global_settings.rec_source == AUDIO_SRC_SPDIF) 757 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
759 { 758 {
760 /* Can't measure S/PDIF sample rate on Archos/Sim yet */ 759 /* Can't measure S/PDIF sample rate on Archos/Sim yet */
761 strncpy(buffer, "--", sizeof(buffer)); 760 strlcpy(buffer, "--", sizeof(buffer));
762 } 761 }
763 else 762 else
764#endif /* HAVE_SPDIF_IN */ 763#endif /* HAVE_SPDIF_IN */
765 { 764 {
766 static char const * const freq_strings[12] = 765 static char const * const freq_strings[12] =
767 { "44", "48", "32", "22", "24", "16" }; 766 { "44", "48", "32", "22", "24", "16" };
768 strncpy(buffer, freq_strings[global_settings.rec_frequency], 767 strlcpy(buffer, freq_strings[global_settings.rec_frequency],
769 sizeof(buffer)); 768 sizeof(buffer));
770 } 769 }
771 770
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index 09bcab8443..8ae83924c2 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -1489,8 +1489,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
1489 break; 1489 break;
1490 } 1490 }
1491 1491
1492 strncpy(stringbuf, string_start, len); 1492 strlcpy(stringbuf, string_start, len+1);
1493 *(stringbuf + len) = '\0';
1494 1493
1495 data->strings[data->num_strings] = stringbuf; 1494 data->strings[data->num_strings] = stringbuf;
1496 stringbuf += len + 1; 1495 stringbuf += len + 1;
@@ -1781,11 +1780,9 @@ bool wps_data_load(struct wps_data *wps_data,
1781#ifdef HAVE_LCD_BITMAP 1780#ifdef HAVE_LCD_BITMAP
1782 /* get the bitmap dir */ 1781 /* get the bitmap dir */
1783 char bmpdir[MAX_PATH]; 1782 char bmpdir[MAX_PATH];
1784 size_t bmpdirlen;
1785 char *dot = strrchr(buf, '.'); 1783 char *dot = strrchr(buf, '.');
1786 bmpdirlen = dot - buf; 1784
1787 strncpy(bmpdir, buf, dot - buf); 1785 strlcpy(bmpdir, buf, dot - buf + 1);
1788 bmpdir[bmpdirlen] = 0;
1789 1786
1790 /* load the bitmaps that were found by the parsing */ 1787 /* load the bitmaps that were found by the parsing */
1791 if (!load_wps_bitmaps(wps_data, bmpdir)) { 1788 if (!load_wps_bitmaps(wps_data, bmpdir)) {
diff --git a/apps/iap.c b/apps/iap.c
index 51f5e5900b..592bbdbbf8 100644
--- a/apps/iap.c
+++ b/apps/iap.c
@@ -495,6 +495,7 @@ void iap_handlepkt(void)
495 unsigned char data[70] = {0x04, 0x00, 0xFF}; 495 unsigned char data[70] = {0x04, 0x00, 0xFF};
496 struct mp3entry id3; 496 struct mp3entry id3;
497 int fd; 497 int fd;
498 size_t len;
498 long tracknum = (signed long)serbuf[4] << 24 | 499 long tracknum = (signed long)serbuf[4] << 24 |
499 (signed long)serbuf[5] << 16 | 500 (signed long)serbuf[5] << 16 |
500 (signed long)serbuf[6] << 8 | serbuf[7]; 501 (signed long)serbuf[6] << 8 | serbuf[7];
@@ -520,16 +521,16 @@ void iap_handlepkt(void)
520 switch(serbuf[3]) 521 switch(serbuf[3])
521 { 522 {
522 case 0x20: 523 case 0x20:
523 strncpy((char *)&data[3], id3.title, 64); 524 len = strlcpy((char *)&data[3], id3.title, 64);
524 iap_send_pkt(data, 4+strlen(id3.title)); 525 iap_send_pkt(data, 4+len);
525 break; 526 break;
526 case 0x22: 527 case 0x22:
527 strncpy((char *)&data[3], id3.artist, 64); 528 len = strlcpy((char *)&data[3], id3.artist, 64);
528 iap_send_pkt(data, 4+strlen(id3.artist)); 529 iap_send_pkt(data, 4+len);
529 break; 530 break;
530 case 0x24: 531 case 0x24:
531 strncpy((char *)&data[3], id3.album, 64); 532 len = strlcpy((char *)&data[3], id3.album, 64);
532 iap_send_pkt(data, 4+strlen(id3.album)); 533 iap_send_pkt(data, 4+len);
533 break; 534 break;
534 } 535 }
535 break; 536 break;
diff --git a/apps/menu.c b/apps/menu.c
index aff84c72e3..f6d0ef967d 100644
--- a/apps/menu.c
+++ b/apps/menu.c
@@ -321,7 +321,7 @@ void do_setting_from_menu(const struct menu_item_ex *temp,
321 while (i < MAX_PATH-1) 321 while (i < MAX_PATH-1)
322 { 322 {
323 int padlen = MIN(len, MAX_PATH-1-i); 323 int padlen = MIN(len, MAX_PATH-1-i);
324 strncpy(&padded_title[i], title, padlen); 324 strlcpy(&padded_title[i], title, padlen);
325 i += padlen; 325 i += padlen;
326 if (i<MAX_PATH-1) 326 if (i<MAX_PATH-1)
327 padded_title[i++] = ' '; 327 padded_title[i++] = ' ';
diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c
index 01b4dbe07a..76ed01d9ba 100644
--- a/apps/menus/main_menu.c
+++ b/apps/menus/main_menu.c
@@ -425,7 +425,7 @@ static void sleep_timer_formatter(char* buffer, size_t buffer_size, int value,
425 minutes = value - (hours * 60); 425 minutes = value - (hours * 60);
426 snprintf(buffer, buffer_size, "%d:%02d", hours, minutes); 426 snprintf(buffer, buffer_size, "%d:%02d", hours, minutes);
427 } else { 427 } else {
428 strncpy(buffer, str(LANG_OFF), buffer_size); 428 strlcpy(buffer, str(LANG_OFF), buffer_size);
429 } 429 }
430} 430}
431 431
diff --git a/apps/metadata.c b/apps/metadata.c
index 6003e1977e..b995e11d95 100644
--- a/apps/metadata.c
+++ b/apps/metadata.c
@@ -403,7 +403,7 @@ bool get_metadata(struct mp3entry* id3, int fd, const char* trackname)
403#endif 403#endif
404 404
405 lseek(fd, 0, SEEK_SET); 405 lseek(fd, 0, SEEK_SET);
406 strncpy(id3->path, trackname, sizeof(id3->path)); 406 strlcpy(id3->path, trackname, sizeof(id3->path));
407 407
408 return true; 408 return true;
409} 409}
diff --git a/apps/metadata/metadata_common.c b/apps/metadata/metadata_common.c
index 38761e3dae..5947098f12 100644
--- a/apps/metadata/metadata_common.c
+++ b/apps/metadata/metadata_common.c
@@ -320,10 +320,9 @@ long parse_tag(const char* name, char* value, struct mp3entry* id3,
320 320
321 if (len > 0) 321 if (len > 0)
322 { 322 {
323 strncpy(buf, value, len);
324 buf[len] = 0;
325 *p = buf;
326 len++; 323 len++;
324 strlcpy(buf, value, len);
325 *p = buf;
327 } 326 }
328 else 327 else
329 { 328 {
diff --git a/apps/metadata/mp3.c b/apps/metadata/mp3.c
index d3adc5d6ae..f02700055a 100644
--- a/apps/metadata/mp3.c
+++ b/apps/metadata/mp3.c
@@ -309,8 +309,7 @@ static int parseuser( struct mp3entry* entry, char* tag, int bufferpos )
309 value_len = bufferpos - (tag - entry->id3v2buf); 309 value_len = bufferpos - (tag - entry->id3v2buf);
310 310
311 if (!strcasecmp(tag, "ALBUM ARTIST")) { 311 if (!strcasecmp(tag, "ALBUM ARTIST")) {
312 strncpy(tag, value, value_len); 312 strlcpy(tag, value, value_len);
313 tag[value_len - 1] = 0;
314 entry->albumartist = tag; 313 entry->albumartist = tag;
315#if CONFIG_CODEC == SWCODEC 314#if CONFIG_CODEC == SWCODEC
316 } else { 315 } else {
@@ -1114,7 +1113,7 @@ bool get_mp3_metadata(int fd, struct mp3entry *entry, const char *filename)
1114 memset(entry, 0, sizeof(struct mp3entry)); 1113 memset(entry, 0, sizeof(struct mp3entry));
1115#endif 1114#endif
1116 1115
1117 strncpy(entry->path, filename, sizeof(entry->path)); 1116 strlcpy(entry->path, filename, sizeof(entry->path));
1118 1117
1119 entry->title = NULL; 1118 entry->title = NULL;
1120 entry->filesize = filesize(fd); 1119 entry->filesize = filesize(fd);
diff --git a/apps/misc.c b/apps/misc.c
index cf356a37f9..e6f8ca840b 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -814,15 +814,13 @@ char *strip_extension(char* buffer, int buffer_size, const char *filename)
814 { 814 {
815 len = dot - filename; 815 len = dot - filename;
816 len = MIN(len, buffer_size); 816 len = MIN(len, buffer_size);
817 strncpy(buffer, filename, len);
818 } 817 }
819 else 818 else
820 { 819 {
821 len = buffer_size; 820 len = buffer_size;
822 strncpy(buffer, filename, buffer_size);
823 } 821 }
824 822
825 buffer[len] = 0; 823 strlcpy(buffer, filename, len + 1);
826 824
827 return buffer; 825 return buffer;
828} 826}
diff --git a/apps/mpeg.c b/apps/mpeg.c
index 8518ab68e6..0e1217b5c8 100644
--- a/apps/mpeg.c
+++ b/apps/mpeg.c
@@ -2203,8 +2203,7 @@ void audio_record(const char *filename)
2203{ 2203{
2204 mpeg_errno = 0; 2204 mpeg_errno = 0;
2205 2205
2206 strncpy(recording_filename, filename, MAX_PATH - 1); 2206 strlcpy(recording_filename, filename, MAX_PATH);
2207 recording_filename[MAX_PATH - 1] = 0;
2208 2207
2209 queue_post(&mpeg_queue, MPEG_RECORD, 0); 2208 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2210} 2209}
@@ -2509,8 +2508,7 @@ void audio_new_file(const char *filename)
2509{ 2508{
2510 mpeg_errno = 0; 2509 mpeg_errno = 0;
2511 2510
2512 strncpy(recording_filename, filename, MAX_PATH - 1); 2511 strlcpy(recording_filename, filename, MAX_PATH);
2513 recording_filename[MAX_PATH - 1] = 0;
2514 2512
2515 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0); 2513 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2516} 2514}
diff --git a/apps/onplay.c b/apps/onplay.c
index 621bf82607..9f38b32fb4 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -532,7 +532,7 @@ static bool delete_handler(bool is_dir)
532 { 532 {
533 char pathname[MAX_PATH]; /* space to go deep */ 533 char pathname[MAX_PATH]; /* space to go deep */
534 cpu_boost(true); 534 cpu_boost(true);
535 strncpy(pathname, file_to_delete, sizeof pathname); 535 strlcpy(pathname, file_to_delete, sizeof(pathname));
536 res = remove_dir(pathname, sizeof(pathname)); 536 res = remove_dir(pathname, sizeof(pathname));
537 cpu_boost(false); 537 cpu_boost(false);
538 } 538 }
@@ -578,7 +578,7 @@ static bool rename_file(void)
578 char newname[MAX_PATH]; 578 char newname[MAX_PATH];
579 char* ptr = strrchr(selected_file, '/') + 1; 579 char* ptr = strrchr(selected_file, '/') + 1;
580 int pathlen = (ptr - selected_file); 580 int pathlen = (ptr - selected_file);
581 strncpy(newname, selected_file, sizeof newname); 581 strlcpy(newname, selected_file, sizeof(newname));
582 if (!kbd_input(newname + pathlen, (sizeof newname)-pathlen)) { 582 if (!kbd_input(newname + pathlen, (sizeof newname)-pathlen)) {
583 if (!strlen(newname + pathlen) || 583 if (!strlen(newname + pathlen) ||
584 (rename(selected_file, newname) < 0)) { 584 (rename(selected_file, newname) < 0)) {
@@ -638,7 +638,7 @@ static bool properties(void)
638static bool clipboard_clip(bool copy) 638static bool clipboard_clip(bool copy)
639{ 639{
640 clipboard_selection[0] = 0; 640 clipboard_selection[0] = 0;
641 strncpy(clipboard_selection, selected_file, sizeof(clipboard_selection)); 641 strlcpy(clipboard_selection, selected_file, sizeof(clipboard_selection));
642 clipboard_selection_attr = selected_file_attr; 642 clipboard_selection_attr = selected_file_attr;
643 clipboard_is_copy = copy; 643 clipboard_is_copy = copy;
644 644
@@ -895,15 +895,15 @@ static bool clipboard_paste(void)
895 } 895 }
896 else 896 else
897 { 897 {
898 strncpy(srcpath, clipboard_selection, sizeof(srcpath)); 898 strlcpy(srcpath, clipboard_selection, sizeof(srcpath));
899 strncpy(targetpath, target, sizeof(targetpath)); 899 strlcpy(targetpath, target, sizeof(targetpath));
900 900
901 success = clipboard_pastedirectory(srcpath, sizeof(srcpath), 901 success = clipboard_pastedirectory(srcpath, sizeof(srcpath),
902 target, sizeof(targetpath), clipboard_is_copy); 902 target, sizeof(targetpath), clipboard_is_copy);
903 903
904 if (success && !clipboard_is_copy) 904 if (success && !clipboard_is_copy)
905 { 905 {
906 strncpy(srcpath, clipboard_selection, sizeof(srcpath)); 906 strlcpy(srcpath, clipboard_selection, sizeof(srcpath));
907 remove_dir(srcpath, sizeof(srcpath)); 907 remove_dir(srcpath, sizeof(srcpath));
908 } 908 }
909 } 909 }
@@ -1026,7 +1026,7 @@ MENUITEM_FUNCTION(set_backdrop_item, 0, ID2P(LANG_SET_AS_BACKDROP),
1026#ifdef HAVE_RECORDING 1026#ifdef HAVE_RECORDING
1027static bool set_recdir(void) 1027static bool set_recdir(void)
1028{ 1028{
1029 strncpy(global_settings.rec_directory, 1029 strlcpy(global_settings.rec_directory,
1030 selected_file, MAX_FILENAME+1); 1030 selected_file, MAX_FILENAME+1);
1031 settings_save(); 1031 settings_save();
1032 return false; 1032 return false;
diff --git a/apps/playback.c b/apps/playback.c
index 4af457cd44..cee89d3bbb 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -617,7 +617,7 @@ struct mp3entry* audio_current_track(void)
617 return write_id3; 617 return write_id3;
618#endif 618#endif
619 619
620 strncpy(write_id3->path, filename, sizeof(write_id3->path)-1); 620 strlcpy(write_id3->path, filename, sizeof(write_id3->path));
621 write_id3->title = strrchr(write_id3->path, '/'); 621 write_id3->title = strrchr(write_id3->path, '/');
622 if (!write_id3->title) 622 if (!write_id3->title)
623 write_id3->title = &write_id3->path[0]; 623 write_id3->title = &write_id3->path[0];
diff --git a/apps/playlist.c b/apps/playlist.c
index 1d291cf6d0..b70fdc8a1f 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -1349,8 +1349,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1349 1349
1350 if (playlist->in_ram && !control_file && max < 0) 1350 if (playlist->in_ram && !control_file && max < 0)
1351 { 1351 {
1352 strncpy(tmp_buf, &playlist->buffer[seek], sizeof(tmp_buf)); 1352 strlcpy(tmp_buf, &playlist->buffer[seek], sizeof(tmp_buf));
1353 tmp_buf[MAX_PATH] = '\0';
1354 max = strlen(tmp_buf) + 1; 1353 max = strlen(tmp_buf) + 1;
1355 } 1354 }
1356 else if (max < 0) 1355 else if (max < 0)
@@ -1402,8 +1401,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1402 } 1401 }
1403 } 1402 }
1404 1403
1405 strncpy(dir_buf, playlist->filename, playlist->dirlen-1); 1404 strlcpy(dir_buf, playlist->filename, playlist->dirlen);
1406 dir_buf[playlist->dirlen-1] = 0;
1407 1405
1408 return (format_track_path(buf, tmp_buf, buf_length, max, dir_buf)); 1406 return (format_track_path(buf, tmp_buf, buf_length, max, dir_buf));
1409} 1407}
@@ -1471,8 +1469,7 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
1471 else 1469 else
1472 { 1470 {
1473 /* start with current directory */ 1471 /* start with current directory */
1474 strncpy(dir, playlist->filename, playlist->dirlen-1); 1472 strlcpy(dir, playlist->filename, playlist->dirlen);
1475 dir[playlist->dirlen-1] = '\0';
1476 } 1473 }
1477 1474
1478 /* use the tree browser dircache to load files */ 1475 /* use the tree browser dircache to load files */
@@ -1671,13 +1668,13 @@ static int format_track_path(char *dest, char *src, int buf_length, int max,
1671 1668
1672 if('/' == src[0]) 1669 if('/' == src[0])
1673 { 1670 {
1674 strncpy(dest, src, buf_length); 1671 strlcpy(dest, src, buf_length);
1675 } 1672 }
1676 else 1673 else
1677 { 1674 {
1678 /* handle dos style drive letter */ 1675 /* handle dos style drive letter */
1679 if (':' == src[1]) 1676 if (':' == src[1])
1680 strncpy(dest, &src[2], buf_length); 1677 strlcpy(dest, &src[2], buf_length);
1681 else if (!strncmp(src, "../", 3)) 1678 else if (!strncmp(src, "../", 3))
1682 { 1679 {
1683 /* handle relative paths */ 1680 /* handle relative paths */
@@ -1904,7 +1901,7 @@ void playlist_init(void)
1904 struct playlist_info* playlist = &current_playlist; 1901 struct playlist_info* playlist = &current_playlist;
1905 1902
1906 playlist->current = true; 1903 playlist->current = true;
1907 strncpy(playlist->control_filename, PLAYLIST_CONTROL_FILE, 1904 strlcpy(playlist->control_filename, PLAYLIST_CONTROL_FILE,
1908 sizeof(playlist->control_filename)); 1905 sizeof(playlist->control_filename));
1909 playlist->fd = -1; 1906 playlist->fd = -1;
1910 playlist->control_fd = -1; 1907 playlist->control_fd = -1;
@@ -2721,7 +2718,7 @@ int playlist_set_current(struct playlist_info* playlist)
2721 2718
2722 empty_playlist(&current_playlist, false); 2719 empty_playlist(&current_playlist, false);
2723 2720
2724 strncpy(current_playlist.filename, playlist->filename, 2721 strlcpy(current_playlist.filename, playlist->filename,
2725 sizeof(current_playlist.filename)); 2722 sizeof(current_playlist.filename));
2726 2723
2727 current_playlist.utf8 = playlist->utf8; 2724 current_playlist.utf8 = playlist->utf8;
@@ -3240,7 +3237,7 @@ char *playlist_name(const struct playlist_info* playlist, char *buf,
3240 if (!playlist) 3237 if (!playlist)
3241 playlist = &current_playlist; 3238 playlist = &current_playlist;
3242 3239
3243 strncpy(buf, playlist->filename+playlist->dirlen, buf_size); 3240 strlcpy(buf, playlist->filename+playlist->dirlen, buf_size);
3244 3241
3245 if (!buf[0]) 3242 if (!buf[0])
3246 return NULL; 3243 return NULL;
@@ -3260,7 +3257,7 @@ char *playlist_get_name(const struct playlist_info* playlist, char *buf,
3260 if (!playlist) 3257 if (!playlist)
3261 playlist = &current_playlist; 3258 playlist = &current_playlist;
3262 3259
3263 strncpy(buf, playlist->filename, buf_size); 3260 strlcpy(buf, playlist->filename, buf_size);
3264 3261
3265 if (!buf[0]) 3262 if (!buf[0])
3266 return NULL; 3263 return NULL;
diff --git a/apps/playlist_catalog.c b/apps/playlist_catalog.c
index 84a62e3474..a4950e22e8 100644
--- a/apps/playlist_catalog.c
+++ b/apps/playlist_catalog.c
@@ -78,7 +78,7 @@ static int initialize_catalog(void)
78 78
79 /* fall back to default directory if no or invalid config */ 79 /* fall back to default directory if no or invalid config */
80 if (default_dir) 80 if (default_dir)
81 strncpy(playlist_dir, PLAYLIST_CATALOG_DEFAULT_DIR, 81 strlcpy(playlist_dir, PLAYLIST_CATALOG_DEFAULT_DIR,
82 sizeof(playlist_dir)); 82 sizeof(playlist_dir));
83 83
84 playlist_dir_length = strlen(playlist_dir); 84 playlist_dir_length = strlen(playlist_dir);
@@ -189,7 +189,7 @@ static char* playlist_callback_name(int selected_item, void* data,
189{ 189{
190 char** playlists = (char**) data; 190 char** playlists = (char**) data;
191 191
192 strncpy(buffer, playlists[selected_item], buffer_len); 192 strlcpy(buffer, playlists[selected_item], buffer_len);
193 193
194 if (buffer[0] != '.' && !(global_settings.show_filename_ext == 1 194 if (buffer[0] != '.' && !(global_settings.show_filename_ext == 1
195 || (global_settings.show_filename_ext == 3 195 || (global_settings.show_filename_ext == 3
@@ -478,7 +478,7 @@ bool catalog_add_to_a_playlist(const char* sel, int sel_attr,
478 478
479 if (add_to_playlist(playlist, new_playlist, sel, sel_attr) == 0) 479 if (add_to_playlist(playlist, new_playlist, sel, sel_attr) == 0)
480 { 480 {
481 strncpy(most_recent_playlist, playlist+playlist_dir_length+1, 481 strlcpy(most_recent_playlist, playlist+playlist_dir_length+1,
482 sizeof(most_recent_playlist)); 482 sizeof(most_recent_playlist));
483 return true; 483 return true;
484 } 484 }
diff --git a/apps/plugin.c b/apps/plugin.c
index f08a98753a..b8c4efdc41 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -381,7 +381,7 @@ static const struct plugin_api rockbox_api = {
381 snprintf, 381 snprintf,
382 vsnprintf, 382 vsnprintf,
383 strcpy, 383 strcpy,
384 strncpy, 384 strlcpy,
385 strlen, 385 strlen,
386 strrchr, 386 strrchr,
387 strcmp, 387 strcmp,
diff --git a/apps/plugin.h b/apps/plugin.h
index bb74d73334..35b2105c17 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -38,6 +38,7 @@
38#include <stdlib.h> 38#include <stdlib.h>
39#include <string.h> 39#include <string.h>
40 40
41char* strncpy(char *, const char *, size_t);
41void* plugin_get_buffer(size_t *buffer_size); 42void* plugin_get_buffer(size_t *buffer_size);
42 43
43#ifndef __PCTOOL__ 44#ifndef __PCTOOL__
@@ -128,12 +129,12 @@ void* plugin_get_buffer(size_t *buffer_size);
128#define PLUGIN_MAGIC 0x526F634B /* RocK */ 129#define PLUGIN_MAGIC 0x526F634B /* RocK */
129 130
130/* increase this every time the api struct changes */ 131/* increase this every time the api struct changes */
131#define PLUGIN_API_VERSION 160 132#define PLUGIN_API_VERSION 161
132 133
133/* update this to latest version if a change to the api struct breaks 134/* update this to latest version if a change to the api struct breaks
134 backwards compatibility (and please take the opportunity to sort in any 135 backwards compatibility (and please take the opportunity to sort in any
135 new function which are "waiting" at the end of the function table) */ 136 new function which are "waiting" at the end of the function table) */
136#define PLUGIN_MIN_API_VERSION 160 137#define PLUGIN_MIN_API_VERSION 161
137 138
138/* plugin return codes */ 139/* plugin return codes */
139enum plugin_status { 140enum plugin_status {
@@ -505,7 +506,7 @@ struct plugin_api {
505 ATTRIBUTE_PRINTF(3, 4); 506 ATTRIBUTE_PRINTF(3, 4);
506 int (*vsnprintf)(char *buf, int size, const char *fmt, va_list ap); 507 int (*vsnprintf)(char *buf, int size, const char *fmt, va_list ap);
507 char* (*strcpy)(char *dst, const char *src); 508 char* (*strcpy)(char *dst, const char *src);
508 char* (*strncpy)(char *dst, const char *src, size_t length); 509 size_t (*strlcpy)(char *dst, const char *src, size_t length);
509 size_t (*strlen)(const char *str); 510 size_t (*strlen)(const char *str);
510 char * (*strrchr)(const char *s, int c); 511 char * (*strrchr)(const char *s, int c);
511 int (*strcmp)(const char *, const char *); 512 int (*strcmp)(const char *, const char *);
diff --git a/apps/plugins/chessbox/chessbox_pgn.c b/apps/plugins/chessbox/chessbox_pgn.c
index a8be179fac..cd163a5e1c 100644
--- a/apps/plugins/chessbox/chessbox_pgn.c
+++ b/apps/plugins/chessbox/chessbox_pgn.c
@@ -543,7 +543,7 @@ char * get_game_text(int selected_item, void *data,
543 rb->snprintf(text_buffer, 50,"%s vs. %s (%s)", temp_node->white_player, 543 rb->snprintf(text_buffer, 50,"%s vs. %s (%s)", temp_node->white_player,
544 temp_node->black_player, temp_node->game_date); 544 temp_node->black_player, temp_node->game_date);
545 545
546 rb->strncpy(buffer, text_buffer, buffer_len); 546 rb->strlcpy(buffer, text_buffer, buffer_len);
547 return buffer; 547 return buffer;
548} 548}
549 549
diff --git a/apps/plugins/dict.c b/apps/plugins/dict.c
index 0c1ddf33a9..fcc55faef1 100644
--- a/apps/plugins/dict.c
+++ b/apps/plugins/dict.c
@@ -283,8 +283,7 @@ enum plugin_status plugin_start(const void* parameter)
283 while (1) 283 while (1)
284 { 284 {
285 /* copy one lcd line */ 285 /* copy one lcd line */
286 rb->strncpy(output, ptr, display_columns); 286 rb->strlcpy(output, ptr, display_columns + 1);
287 output[display_columns] = '\0';
288 287
289 /* typecast to kill a warning... */ 288 /* typecast to kill a warning... */
290 if((int)rb->strlen(ptr) < display_columns) 289 if((int)rb->strlen(ptr) < display_columns)
diff --git a/apps/plugins/doom/rockmacros.h b/apps/plugins/doom/rockmacros.h
index 73cd902277..1ead411b85 100644
--- a/apps/plugins/doom/rockmacros.h
+++ b/apps/plugins/doom/rockmacros.h
@@ -59,7 +59,6 @@ int my_close(int id);
59#define memcmp(a,b,c) rb->memcmp((a),(b),(c)) 59#define memcmp(a,b,c) rb->memcmp((a),(b),(c))
60#define memchr(a,b,c) rb->memchr((a),(b),(c)) 60#define memchr(a,b,c) rb->memchr((a),(b),(c))
61#define strcpy(a,b) rb->strcpy((a),(b)) 61#define strcpy(a,b) rb->strcpy((a),(b))
62#define strncpy(a,b,c) rb->strncpy((a),(b),(c))
63#define strlen(a) rb->strlen((a)) 62#define strlen(a) rb->strlen((a))
64#define strcmp(a,b) rb->strcmp((a),(b)) 63#define strcmp(a,b) rb->strcmp((a),(b))
65#define strncmp(a,b,c) rb->strncmp((a),(b),(c)) 64#define strncmp(a,b,c) rb->strncmp((a),(b),(c))
diff --git a/apps/plugins/goban/sgf_output.c b/apps/plugins/goban/sgf_output.c
index c1ac052be7..6a52789f7a 100644
--- a/apps/plugins/goban/sgf_output.c
+++ b/apps/plugins/goban/sgf_output.c
@@ -130,7 +130,7 @@ output_header_props (void)
130{ 130{
131 char buffer[128]; 131 char buffer[128];
132 132
133 rb->strncpy (buffer, "GM[1]FF[4]CA[UTF-8]AP[Rockbox Goban:1.0]ST[2]\n\n", 133 rb->strlcpy (buffer, "GM[1]FF[4]CA[UTF-8]AP[Rockbox Goban:1.0]ST[2]\n\n",
134 sizeof (buffer)); 134 sizeof (buffer));
135 write_file (sgf_fd, buffer, rb->strlen (buffer)); 135 write_file (sgf_fd, buffer, rb->strlen (buffer));
136 136
diff --git a/apps/plugins/invadrox.c b/apps/plugins/invadrox.c
index c7d5696d19..fa7cb81e02 100644
--- a/apps/plugins/invadrox.c
+++ b/apps/plugins/invadrox.c
@@ -1511,7 +1511,7 @@ void init_invadrox(void)
1511 1511
1512 if (highscore_load(HISCOREFILE, &hiscore, 1) < 0) { 1512 if (highscore_load(HISCOREFILE, &hiscore, 1) < 0) {
1513 /* Init hiscore to 0 */ 1513 /* Init hiscore to 0 */
1514 rb->strncpy(hiscore.name, "Invader", sizeof(hiscore.name)); 1514 rb->strlcpy(hiscore.name, "Invader", sizeof(hiscore.name));
1515 hiscore.score = 0; 1515 hiscore.score = 0;
1516 hiscore.level = 1; 1516 hiscore.level = 1;
1517 } 1517 }
diff --git a/apps/plugins/keybox.c b/apps/plugins/keybox.c
index 08d5131eff..73fd138f09 100644
--- a/apps/plugins/keybox.c
+++ b/apps/plugins/keybox.c
@@ -330,11 +330,11 @@ static void hash_pw(union hash *out)
330static void make_key(void) 330static void make_key(void)
331{ 331{
332 int i; 332 int i;
333 char buf[sizeof(master_pw) + sizeof(salt) + 1]; 333 char buf[sizeof(master_pw) + sizeof(salt) + 1] = {0};
334 struct md5_s key_md5; 334 struct md5_s key_md5;
335 size_t len = rb->strlen(master_pw); 335 size_t len = rb->strlen(master_pw);
336 336
337 rb->strncpy(buf, master_pw, sizeof(buf)); 337 rb->strlcpy(buf, master_pw, sizeof(buf));
338 338
339 rb->memcpy(&buf[len], &salt, sizeof(salt)); 339 rb->memcpy(&buf[len], &salt, sizeof(salt));
340 340
@@ -418,7 +418,7 @@ static int parse_buffer(void)
418 break; 418 break;
419 } 419 }
420 420
421 rb->strncpy(entry->title, start, FIELD_LEN); 421 rb->strlcpy(entry->title, start, FIELD_LEN);
422 start = end + 1; 422 start = end + 1;
423 423
424 end = rb->strchr(start, '\0'); /* find eol */ 424 end = rb->strchr(start, '\0'); /* find eol */
@@ -428,7 +428,7 @@ static int parse_buffer(void)
428 break; 428 break;
429 } 429 }
430 430
431 rb->strncpy(entry->name, start, FIELD_LEN); 431 rb->strlcpy(entry->name, start, FIELD_LEN);
432 start = end + 1; 432 start = end + 1;
433 433
434 end = rb->strchr(start, '\0'); /* find eol */ 434 end = rb->strchr(start, '\0'); /* find eol */
@@ -437,7 +437,7 @@ static int parse_buffer(void)
437 { 437 {
438 break; 438 break;
439 } 439 }
440 rb->strncpy(entry->password, start, FIELD_LEN); 440 rb->strlcpy(entry->password, start, FIELD_LEN);
441 start = end + 1; 441 start = end + 1;
442 entry->used = true; 442 entry->used = true;
443 if (i + 1 < MAX_ENTRIES - 1) 443 if (i + 1 < MAX_ENTRIES - 1)
@@ -469,13 +469,13 @@ static void write_output(int fd)
469 for (i = 0; i < pw_list.num_entries; i++) 469 for (i = 0; i < pw_list.num_entries; i++)
470 { 470 {
471 len = rb->strlen(entry->title); 471 len = rb->strlen(entry->title);
472 rb->strncpy(p, entry->title, len+1); 472 rb->strlcpy(p, entry->title, len+1);
473 p += len+1; 473 p += len+1;
474 len = rb->strlen(entry->name); 474 len = rb->strlen(entry->name);
475 rb->strncpy(p, entry->name, len+1); 475 rb->strlcpy(p, entry->name, len+1);
476 p += len+1; 476 p += len+1;
477 len = rb->strlen(entry->password); 477 len = rb->strlen(entry->password);
478 rb->strncpy(p, entry->password, len+1); 478 rb->strlcpy(p, entry->password, len+1);
479 p += len+1; 479 p += len+1;
480 if (entry->next) 480 if (entry->next)
481 entry = entry->next; 481 entry = entry->next;
@@ -517,7 +517,7 @@ static int enter_pw(char *pw_buf, size_t buflen, bool new_pw)
517 } 517 }
518 else 518 else
519 { 519 {
520 rb->strncpy(pw_buf, buf[0], buflen); 520 rb->strlcpy(pw_buf, buf[0], buflen);
521 hash_pw(&pwhash); 521 hash_pw(&pwhash);
522 return 0; 522 return 0;
523 } 523 }
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index 02adb7089c..72538fc2a0 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -6,6 +6,7 @@ playback_control.c
6rgb_hsv.c 6rgb_hsv.c
7buflib.c 7buflib.c
8display_text.c 8display_text.c
9strncpy.c
9#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) 10#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4)
10grey_core.c 11grey_core.c
11grey_draw.c 12grey_draw.c
diff --git a/apps/plugins/lib/configfile.c b/apps/plugins/lib/configfile.c
index 5e1e776f39..21b66a317b 100644
--- a/apps/plugins/lib/configfile.c
+++ b/apps/plugins/lib/configfile.c
@@ -139,7 +139,7 @@ int configfile_load(const char *filename, struct configdata *cfg,
139 break; 139 break;
140 140
141 case TYPE_STRING: 141 case TYPE_STRING:
142 rb->strncpy(cfg[i].string, val, cfg[i].max); 142 rb->strlcpy(cfg[i].string, val, cfg[i].max);
143 break; 143 break;
144 } 144 }
145 } 145 }
diff --git a/apps/plugins/lib/highscore.c b/apps/plugins/lib/highscore.c
index e8e1c883b0..15ebb05f4d 100644
--- a/apps/plugins/lib/highscore.c
+++ b/apps/plugins/lib/highscore.c
@@ -72,7 +72,7 @@ int highscore_load(char *filename, struct highscore *scores, int num_scores)
72 72
73 scores[i].score = rb->atoi(score); 73 scores[i].score = rb->atoi(score);
74 scores[i].level = rb->atoi(level); 74 scores[i].level = rb->atoi(level);
75 rb->strncpy(scores[i].name, name, sizeof(scores[i].name)-1); 75 rb->strlcpy(scores[i].name, name, sizeof(scores[i].name));
76 i++; 76 i++;
77 } 77 }
78 rb->close(fd); 78 rb->close(fd);
@@ -100,8 +100,7 @@ int highscore_update(int score, int level, const char *name,
100 entry = scores + pos; 100 entry = scores + pos;
101 entry->score = score; 101 entry->score = score;
102 entry->level = level; 102 entry->level = level;
103 rb->strncpy(entry->name, name, sizeof(entry->name)); 103 rb->strlcpy(entry->name, name, sizeof(entry->name));
104 entry->name[sizeof(entry->name)-1] = '\0';
105 104
106 return pos; 105 return pos;
107} 106}
diff --git a/firmware/common/strncpy.c b/apps/plugins/lib/strncpy.c
index 7c1973ba66..7c1973ba66 100644
--- a/firmware/common/strncpy.c
+++ b/apps/plugins/lib/strncpy.c
diff --git a/apps/plugins/lib/wrappers.h b/apps/plugins/lib/wrappers.h
index 5eb45d02c8..b6fbd51a39 100644
--- a/apps/plugins/lib/wrappers.h
+++ b/apps/plugins/lib/wrappers.h
@@ -51,7 +51,7 @@
51#define strcpy rb->strcpy 51#define strcpy rb->strcpy
52#define strip_extension rb->strip_extension 52#define strip_extension rb->strip_extension
53#define strlen rb->strlen 53#define strlen rb->strlen
54#define strncpy rb->strncpy 54#define strlcpy rb->strlcpy
55#define strrchr rb->strrchr 55#define strrchr rb->strrchr
56 56
57#endif 57#endif
diff --git a/apps/plugins/lua/lobject.c b/apps/plugins/lua/lobject.c
index 62ad8e9359..7f73114303 100644
--- a/apps/plugins/lua/lobject.c
+++ b/apps/plugins/lua/lobject.c
@@ -181,8 +181,7 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
181 181
182void luaO_chunkid (char *out, const char *source, size_t bufflen) { 182void luaO_chunkid (char *out, const char *source, size_t bufflen) {
183 if (*source == '=') { 183 if (*source == '=') {
184 strncpy(out, source+1, bufflen); /* remove first char */ 184 strlcpy(out, source+1, bufflen); /* remove first char */
185 out[bufflen-1] = '\0'; /* ensures null termination */
186 } 185 }
187 else { /* out = "source", or "...source" */ 186 else { /* out = "source", or "...source" */
188 if (*source == '@') { 187 if (*source == '@') {
diff --git a/apps/plugins/lua/lstrlib.c b/apps/plugins/lua/lstrlib.c
index 3d6103692f..4d58280ba8 100644
--- a/apps/plugins/lua/lstrlib.c
+++ b/apps/plugins/lua/lstrlib.c
@@ -737,9 +737,7 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
737 if (isdigit(uchar(*p))) 737 if (isdigit(uchar(*p)))
738 luaL_error(L, "invalid format (width or precision too long)"); 738 luaL_error(L, "invalid format (width or precision too long)");
739 *(form++) = '%'; 739 *(form++) = '%';
740 strncpy(form, strfrmt, p - strfrmt + 1); 740 strlcpy(form, strfrmt, p - strfrmt + 1);
741 form += p - strfrmt + 1;
742 *form = '\0';
743 return p; 741 return p;
744} 742}
745 743
diff --git a/apps/plugins/lua/rockconf.h b/apps/plugins/lua/rockconf.h
index 639f336b5b..02bd0e76d1 100644
--- a/apps/plugins/lua/rockconf.h
+++ b/apps/plugins/lua/rockconf.h
@@ -63,7 +63,7 @@ long pow(long x, long y);
63#define strchr rb->strchr 63#define strchr rb->strchr
64#define strcmp rb->strcmp 64#define strcmp rb->strcmp
65#define strcpy rb->strcpy 65#define strcpy rb->strcpy
66#define strncpy rb->strncpy 66#define strlcpy rb->strlcpy
67#define strlen rb->strlen 67#define strlen rb->strlen
68 68
69#endif /* _ROCKCONF_H_ */ 69#endif /* _ROCKCONF_H_ */
diff --git a/apps/plugins/mp3_encoder.c b/apps/plugins/mp3_encoder.c
index 6849daf2f3..9da0d6925f 100644
--- a/apps/plugins/mp3_encoder.c
+++ b/apps/plugins/mp3_encoder.c
@@ -2399,9 +2399,8 @@ char mp3_name[80];
2399 2399
2400void get_mp3_filename(const char *wav_name) 2400void get_mp3_filename(const char *wav_name)
2401{ 2401{
2402 int slen = rb->strlen(wav_name); 2402 rb->strlcpy(mp3_name, wav_name, sizeof(mp3_name));
2403 rb->strncpy(mp3_name, wav_name, 79); 2403 rb->strlcpy(mp3_name + rb->strlen(mp3_name) - 4, ".mp3", 5);
2404 rb->strncpy(mp3_name + slen - 4, ".mp3", 5);
2405} 2404}
2406 2405
2407#if CONFIG_KEYPAD == IRIVER_H100_PAD || CONFIG_KEYPAD == IRIVER_H300_PAD 2406#if CONFIG_KEYPAD == IRIVER_H100_PAD || CONFIG_KEYPAD == IRIVER_H300_PAD
diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c
index 7ec1157615..a9b66fc22f 100644
--- a/apps/plugins/mpegplayer/mpeg_settings.c
+++ b/apps/plugins/mpegplayer/mpeg_settings.c
@@ -344,7 +344,7 @@ static void backlight_brightness_formatter(char *buf, size_t length,
344 int value, const char *input) 344 int value, const char *input)
345{ 345{
346 if (value < 0) 346 if (value < 0)
347 rb->strncpy(buf, BACKLIGHT_OPTION_DEFAULT, length); 347 rb->strlcpy(buf, BACKLIGHT_OPTION_DEFAULT, length);
348 else 348 else
349 rb->snprintf(buf, length, "%d", value + MIN_BRIGHTNESS_SETTING); 349 rb->snprintf(buf, length, "%d", value + MIN_BRIGHTNESS_SETTING);
350 350
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c
index 496e9c94df..34d1db5d5c 100644
--- a/apps/plugins/pictureflow/pictureflow.c
+++ b/apps/plugins/pictureflow/pictureflow.c
@@ -913,7 +913,7 @@ bool get_albumart_for_index_from_db(const int slide_index, char *buf,
913{ 913{
914 if ( slide_index == -1 ) 914 if ( slide_index == -1 )
915 { 915 {
916 rb->strncpy( buf, EMPTY_SLIDE, buflen ); 916 rb->strlcpy( buf, EMPTY_SLIDE, buflen );
917 } 917 }
918 918
919 if (!rb->tagcache_search(&tcs, tag_filename)) 919 if (!rb->tagcache_search(&tcs, tag_filename))
@@ -930,8 +930,7 @@ bool get_albumart_for_index_from_db(const int slide_index, char *buf,
930#ifdef HAVE_TC_RAMCACHE 930#ifdef HAVE_TC_RAMCACHE
931 if (rb->tagcache_fill_tags(&id3, tcs.result)) 931 if (rb->tagcache_fill_tags(&id3, tcs.result))
932 { 932 {
933 rb->strncpy(id3.path, tcs.result, sizeof(id3.path)); 933 rb->strlcpy(id3.path, tcs.result, sizeof(id3.path));
934 id3.path[sizeof(id3.path) - 1] = 0;
935 } 934 }
936 else 935 else
937#endif 936#endif
diff --git a/apps/plugins/properties.c b/apps/plugins/properties.c
index 18beec2da6..b57150b817 100644
--- a/apps/plugins/properties.c
+++ b/apps/plugins/properties.c
@@ -70,8 +70,7 @@ static bool file_properties(char* selected_file)
70 70
71 char* ptr = rb->strrchr(selected_file, '/') + 1; 71 char* ptr = rb->strrchr(selected_file, '/') + 1;
72 int dirlen = (ptr - selected_file); 72 int dirlen = (ptr - selected_file);
73 rb->strncpy(tstr, selected_file, dirlen); 73 rb->strlcpy(tstr, selected_file, dirlen + 1);
74 tstr[dirlen] = 0;
75 74
76 dir = rb->opendir(tstr); 75 dir = rb->opendir(tstr);
77 if (dir) 76 if (dir)
@@ -212,7 +211,7 @@ static bool dir_properties(char* selected_file)
212{ 211{
213 DPS dps; 212 DPS dps;
214 char tstr[64]; 213 char tstr[64];
215 rb->strncpy(dps.dirname, selected_file, MAX_PATH); 214 rb->strlcpy(dps.dirname, selected_file, MAX_PATH);
216 dps.len = MAX_PATH; 215 dps.len = MAX_PATH;
217 dps.dc = 0; 216 dps.dc = 0;
218 dps.fc = 0; 217 dps.fc = 0;
@@ -220,7 +219,7 @@ static bool dir_properties(char* selected_file)
220 if(false == _dir_properties(&dps)) 219 if(false == _dir_properties(&dps))
221 return false; 220 return false;
222 221
223 rb->strncpy(str_dirname, selected_file, MAX_PATH); 222 rb->strlcpy(str_dirname, selected_file, MAX_PATH);
224 rb->snprintf(str_dircount, sizeof str_dircount, "Subdirs: %d", dps.dc); 223 rb->snprintf(str_dircount, sizeof str_dircount, "Subdirs: %d", dps.dc);
225 rb->snprintf(str_filecount, sizeof str_filecount, "Files: %d", dps.fc); 224 rb->snprintf(str_filecount, sizeof str_filecount, "Files: %d", dps.fc);
226 rb->snprintf(str_size, sizeof str_size, "Size: %s", 225 rb->snprintf(str_size, sizeof str_size, "Size: %s",
@@ -236,35 +235,35 @@ char * get_props(int selected_item, void* data, char *buffer, size_t buffer_len)
236 switch(selected_item) 235 switch(selected_item)
237 { 236 {
238 case 0: 237 case 0:
239 rb->strncpy(buffer, str_dirname, buffer_len); 238 rb->strlcpy(buffer, str_dirname, buffer_len);
240 break; 239 break;
241 case 1: 240 case 1:
242 rb->strncpy(buffer, its_a_dir ? str_dircount : str_filename, 241 rb->strlcpy(buffer, its_a_dir ? str_dircount : str_filename,
243 buffer_len); 242 buffer_len);
244 break; 243 break;
245 case 2: 244 case 2:
246 rb->strncpy(buffer, its_a_dir ? str_filecount : str_size, buffer_len); 245 rb->strlcpy(buffer, its_a_dir ? str_filecount : str_size, buffer_len);
247 break; 246 break;
248 case 3: 247 case 3:
249 rb->strncpy(buffer, its_a_dir ? str_size : str_date, buffer_len); 248 rb->strlcpy(buffer, its_a_dir ? str_size : str_date, buffer_len);
250 break; 249 break;
251 case 4: 250 case 4:
252 rb->strncpy(buffer, its_a_dir ? "" : str_time, buffer_len); 251 rb->strlcpy(buffer, its_a_dir ? "" : str_time, buffer_len);
253 break; 252 break;
254 case 5: 253 case 5:
255 rb->strncpy(buffer, its_a_dir ? "" : str_artist, buffer_len); 254 rb->strlcpy(buffer, its_a_dir ? "" : str_artist, buffer_len);
256 break; 255 break;
257 case 6: 256 case 6:
258 rb->strncpy(buffer, its_a_dir ? "" : str_title, buffer_len); 257 rb->strlcpy(buffer, its_a_dir ? "" : str_title, buffer_len);
259 break; 258 break;
260 case 7: 259 case 7:
261 rb->strncpy(buffer, its_a_dir ? "" : str_album, buffer_len); 260 rb->strlcpy(buffer, its_a_dir ? "" : str_album, buffer_len);
262 break; 261 break;
263 case 8: 262 case 8:
264 rb->strncpy(buffer, its_a_dir ? "" : str_duration, buffer_len); 263 rb->strlcpy(buffer, its_a_dir ? "" : str_duration, buffer_len);
265 break; 264 break;
266 default: 265 default:
267 rb->strncpy(buffer, "ERROR", buffer_len); 266 rb->strlcpy(buffer, "ERROR", buffer_len);
268 break; 267 break;
269 } 268 }
270 return buffer; 269 return buffer;
@@ -284,8 +283,7 @@ enum plugin_status plugin_start(const void* parameter)
284 struct dirent* entry; 283 struct dirent* entry;
285 char* ptr = rb->strrchr(file, '/') + 1; 284 char* ptr = rb->strrchr(file, '/') + 1;
286 int dirlen = (ptr - file); 285 int dirlen = (ptr - file);
287 rb->strncpy(str_dirname, file, dirlen); 286 rb->strlcpy(str_dirname, file, dirlen + 1);
288 str_dirname[dirlen] = 0;
289 287
290 dir = rb->opendir(str_dirname); 288 dir = rb->opendir(str_dirname);
291 if (dir) 289 if (dir)
diff --git a/apps/plugins/random_folder_advance_config.c b/apps/plugins/random_folder_advance_config.c
index 28546a340c..c9ffaed319 100644
--- a/apps/plugins/random_folder_advance_config.c
+++ b/apps/plugins/random_folder_advance_config.c
@@ -86,7 +86,7 @@ void traversedir(char* location, char* name)
86 /* check if path is removed directory, if so dont enter it */ 86 /* check if path is removed directory, if so dont enter it */
87 rb->snprintf(path, MAX_PATH, "%s/%s", fullpath, entry->d_name); 87 rb->snprintf(path, MAX_PATH, "%s/%s", fullpath, entry->d_name);
88 while(path[0] == '/') 88 while(path[0] == '/')
89 rb->strncpy(path, path + 1, rb->strlen(path)); 89 rb->strlcpy(path, path + 1, sizeof(path));
90 for(i = 0; i < num_replaced_dirs; i++) 90 for(i = 0; i < num_replaced_dirs; i++)
91 { 91 {
92 if(!rb->strcmp(path, removed_dirs[i])) 92 if(!rb->strcmp(path, removed_dirs[i]))
@@ -141,8 +141,8 @@ bool custom_dir(void)
141 (num_replaced_dirs < MAX_REMOVED_DIRS)) 141 (num_replaced_dirs < MAX_REMOVED_DIRS))
142 { 142 {
143 num_replaced_dirs ++; 143 num_replaced_dirs ++;
144 rb->strncpy(removed_dirs[num_replaced_dirs - 1], line + 2, 144 rb->strlcpy(removed_dirs[num_replaced_dirs - 1], line + 2,
145 rb->strlen(line)); 145 sizeof(line));
146 } 146 }
147 } 147 }
148 rb->close(fd2); 148 rb->close(fd2);
@@ -157,7 +157,7 @@ bool custom_dir(void)
157 { 157 {
158 /* remove preceeding '/'s from the line */ 158 /* remove preceeding '/'s from the line */
159 while(line[0] == '/') 159 while(line[0] == '/')
160 rb->strncpy(line, line + 1, rb->strlen(line)); 160 rb->strlcpy(line, line + 1, sizeof(line));
161 161
162 rb->snprintf(formatted_line, MAX_PATH, "/%s", line); 162 rb->snprintf(formatted_line, MAX_PATH, "/%s", line);
163 163
@@ -237,7 +237,7 @@ void generate(void)
237char *list_get_name_cb(int selected_item, void* data, char* buf, size_t buf_len) 237char *list_get_name_cb(int selected_item, void* data, char* buf, size_t buf_len)
238{ 238{
239 (void)data; 239 (void)data;
240 rb->strncpy(buf, list->folder[selected_item], buf_len); 240 rb->strlcpy(buf, list->folder[selected_item], buf_len);
241 return buf; 241 return buf;
242} 242}
243 243
diff --git a/apps/plugins/rockboy/menu.c b/apps/plugins/rockboy/menu.c
index 9821ce9ba2..76de224294 100644
--- a/apps/plugins/rockboy/menu.c
+++ b/apps/plugins/rockboy/menu.c
@@ -162,11 +162,10 @@ static void munge_name(char *buf, const size_t bufsiz) {
162 * checksum or something like that? 162 * checksum or something like that?
163 */ 163 */
164static void build_slot_path(char *buf, size_t bufsiz, size_t slot_id) { 164static void build_slot_path(char *buf, size_t bufsiz, size_t slot_id) {
165 char name_buf[40]; 165 char name_buf[17];
166 166
167 /* munge state file name */ 167 /* munge state file name */
168 strncpy(name_buf, rom.name, 40); 168 strlcpy(name_buf, rom.name, sizeof(name_buf));
169 name_buf[16] = '\0';
170 munge_name(name_buf, strlen(name_buf)); 169 munge_name(name_buf, strlen(name_buf));
171 170
172 /* glom the whole mess together */ 171 /* glom the whole mess together */
@@ -211,7 +210,7 @@ static bool do_file(char *path, char *desc, bool is_load) {
211 /* build description buffer */ 210 /* build description buffer */
212 memset(desc_buf, 0, 20); 211 memset(desc_buf, 0, 20);
213 if (desc) 212 if (desc)
214 strncpy(desc_buf, desc, 20); 213 strlcpy(desc_buf, desc, 20);
215 214
216 /* save state */ 215 /* save state */
217 write(fd, desc_buf, 20); 216 write(fd, desc_buf, 20);
@@ -241,8 +240,7 @@ static bool do_slot(size_t slot_id, bool is_load) {
241 if (!is_load) 240 if (!is_load)
242 if (rb->kbd_input(desc_buf, 20) || !strlen(desc_buf)) 241 if (rb->kbd_input(desc_buf, 20) || !strlen(desc_buf))
243 { 242 {
244 memset(desc_buf, 0, 20); 243 strlcpy(desc_buf, "Untitled", 20);
245 strncpy(desc_buf, "Untitled", 20);
246 } 244 }
247 245
248 /* load/save file */ 246 /* load/save file */
diff --git a/apps/plugins/rockboy/rockmacros.h b/apps/plugins/rockboy/rockmacros.h
index 414b889003..0fd13f6ef9 100644
--- a/apps/plugins/rockboy/rockmacros.h
+++ b/apps/plugins/rockboy/rockmacros.h
@@ -67,7 +67,7 @@ void dynamic_recompile (struct dynarec_block *newblock);
67#define strcat(a,b) rb->strcat((a),(b)) 67#define strcat(a,b) rb->strcat((a),(b))
68#define memset(a,b,c) rb->memset((a),(b),(c)) 68#define memset(a,b,c) rb->memset((a),(b),(c))
69#define strcpy(a,b) rb->strcpy((a),(b)) 69#define strcpy(a,b) rb->strcpy((a),(b))
70#define strncpy(a,b,c) rb->strncpy((a),(b),(c)) 70#define strlcpy(a,b,c) rb->strlcpy((a),(b),(c))
71#define strlen(a) rb->strlen((a)) 71#define strlen(a) rb->strlen((a))
72#define strcmp(a,b) rb->strcmp((a),(b)) 72#define strcmp(a,b) rb->strcmp((a),(b))
73#define strchr(a,b) rb->strchr((a),(b)) 73#define strchr(a,b) rb->strchr((a),(b))
diff --git a/apps/plugins/rockpaint.c b/apps/plugins/rockpaint.c
index 20bebdd11f..5de6c14a6b 100644
--- a/apps/plugins/rockpaint.c
+++ b/apps/plugins/rockpaint.c
@@ -686,7 +686,7 @@ static bool browse( char *dst, int dst_size, const char *start )
686 if( selected < 0 || selected >= item_count ) 686 if( selected < 0 || selected >= item_count )
687 break; 687 break;
688 struct entry* e = &dc[indexes[selected]]; 688 struct entry* e = &dc[indexes[selected]];
689 rb->strncpy( bbuf_s, e->name, sizeof( bbuf_s ) ); 689 rb->strlcpy( bbuf_s, e->name, sizeof( bbuf_s ) );
690 if( !( e->attr & ATTR_DIRECTORY ) ) 690 if( !( e->attr & ATTR_DIRECTORY ) )
691 { 691 {
692 *tree = backup; 692 *tree = backup;
diff --git a/apps/plugins/shortcuts/shortcuts_common.c b/apps/plugins/shortcuts/shortcuts_common.c
index a06abd3f7f..1a781b23eb 100644
--- a/apps/plugins/shortcuts/shortcuts_common.c
+++ b/apps/plugins/shortcuts/shortcuts_common.c
@@ -213,8 +213,7 @@ bool parse_entry_content(char *line, sc_entry_t *entry, int last_segm)
213 DEBUGF("Bad entry: pathlen=%d, displen=%d\n", path_len, disp_len); 213 DEBUGF("Bad entry: pathlen=%d, displen=%d\n", path_len, disp_len);
214 return false; 214 return false;
215 } 215 }
216 rb->strncpy(entry->path, path, path_len); 216 rb->strlcpy(entry->path, path, path_len + 1);
217 entry->path[path_len] = '\0';
218 rb->strcpy(entry->disp, disp); /* Safe since we've checked the length */ 217 rb->strcpy(entry->disp, disp); /* Safe since we've checked the length */
219 entry->explicit_disp = expl; 218 entry->explicit_disp = expl;
220 return true; 219 return true;
@@ -295,15 +294,14 @@ bool parse_name_value(char *line, char *name, int namesize,
295 /* Too long name */ 294 /* Too long name */
296 return false; 295 return false;
297 } 296 }
298 rb->strncpy(name, line, name_len); 297 rb->strlcpy(name, line, name_len + 1);
299 name[name_len] = '\0';
300 298
301 val_len = rb->strlen(line) - name_len - NAME_VALUE_SEPARATOR_LEN; 299 val_len = rb->strlen(line) - name_len - NAME_VALUE_SEPARATOR_LEN;
302 if (val_len >= valuesize) { 300 if (val_len >= valuesize) {
303 /* Too long value */ 301 /* Too long value */
304 return false; 302 return false;
305 } 303 }
306 rb->strncpy(value, sep+NAME_VALUE_SEPARATOR_LEN, val_len+1); 304 rb->strlcpy(value, sep+NAME_VALUE_SEPARATOR_LEN, val_len+1);
307 return true; 305 return true;
308} 306}
309 307
diff --git a/apps/plugins/sokoban.c b/apps/plugins/sokoban.c
index 8672249bdc..bfd400b408 100644
--- a/apps/plugins/sokoban.c
+++ b/apps/plugins/sokoban.c
@@ -689,7 +689,8 @@ static bool redo(void)
689 689
690static void init_boards(void) 690static void init_boards(void)
691{ 691{
692 rb->strncpy(buffered_boards.filename, SOKOBAN_LEVELS_FILE, MAX_PATH); 692 rb->strlcpy(buffered_boards.filename, SOKOBAN_LEVELS_FILE,
693 sizeof(buffered_boards.filename));
693 694
694 current_info.level.index = 0; 695 current_info.level.index = 0;
695 current_info.player.row = 0; 696 current_info.player.row = 0;
@@ -1026,8 +1027,8 @@ static bool save(char *filename, bool solution)
1026 1027
1027 /* Create dir if it doesn't exist */ 1028 /* Create dir if it doesn't exist */
1028 if ((loc = rb->strrchr(filename, '/')) != NULL) { 1029 if ((loc = rb->strrchr(filename, '/')) != NULL) {
1029 rb->strncpy(dirname, filename, loc - filename); 1030 rb->strlcpy(dirname, filename, loc - filename + 1);
1030 dirname[loc - filename] = '\0'; 1031
1031 if(!(dir = rb->opendir(dirname))) 1032 if(!(dir = rb->opendir(dirname)))
1032 rb->mkdir(dirname); 1033 rb->mkdir(dirname);
1033 else 1034 else
@@ -1082,7 +1083,9 @@ static bool load(char *filename, bool silent)
1082 if (rb->strncmp(buf, "Sokoban", 7) != 0) { 1083 if (rb->strncmp(buf, "Sokoban", 7) != 0) {
1083 rb->close(fd); 1084 rb->close(fd);
1084 1085
1085 rb->strncpy(buffered_boards.filename, filename, MAX_PATH); 1086 rb->strlcpy(buffered_boards.filename, filename,
1087 sizeof(buffered_boards.filename));
1088
1086 if (!read_levels(true)) 1089 if (!read_levels(true))
1087 return false; 1090 return false;
1088 1091
diff --git a/apps/plugins/splitedit.c b/apps/plugins/splitedit.c
index 9f62b7a346..a169a61a47 100644
--- a/apps/plugins/splitedit.c
+++ b/apps/plugins/splitedit.c
@@ -780,11 +780,11 @@ static void save_editor(struct mp3entry *mp3, int splittime)
780 bool part2_save = true; 780 bool part2_save = true;
781 781
782 /* file name for left part */ 782 /* file name for left part */
783 rb->strncpy(part1_name, mp3->path, MAX_PATH); 783 rb->strlcpy(part1_name, mp3->path, MAX_PATH);
784 generateFileName(part1_name, 1); 784 generateFileName(part1_name, 1);
785 785
786 /* file name for right part */ 786 /* file name for right part */
787 rb->strncpy(part2_name, mp3->path, MAX_PATH); 787 rb->strlcpy(part2_name, mp3->path, MAX_PATH);
788 generateFileName(part2_name, 2); 788 generateFileName(part2_name, 2);
789 789
790 while (!exit_request) 790 while (!exit_request)
diff --git a/apps/plugins/sudoku/sudoku.c b/apps/plugins/sudoku/sudoku.c
index f8a438592d..77f6ca7899 100644
--- a/apps/plugins/sudoku/sudoku.c
+++ b/apps/plugins/sudoku/sudoku.c
@@ -603,7 +603,7 @@ void default_state(struct sudoku_state_t* state)
603{ 603{
604 int r,c; 604 int r,c;
605 605
606 rb->strncpy(state->filename,GAME_FILE,MAX_PATH); 606 rb->strlcpy(state->filename,GAME_FILE,MAX_PATH);
607 for (r=0;r<9;r++) { 607 for (r=0;r<9;r++) {
608 for (c=0;c<9;c++) { 608 for (c=0;c<9;c++) {
609 state->startboard[r][c]=default_game[r][c]; 609 state->startboard[r][c]=default_game[r][c];
@@ -626,7 +626,7 @@ void clear_state(struct sudoku_state_t* state)
626{ 626{
627 int r,c; 627 int r,c;
628 628
629 rb->strncpy(state->filename,GAME_FILE,MAX_PATH); 629 rb->strlcpy(state->filename,GAME_FILE,MAX_PATH);
630 for (r=0;r<9;r++) { 630 for (r=0;r<9;r++) {
631 for (c=0;c<9;c++) { 631 for (c=0;c<9;c++) {
632 state->startboard[r][c]='0'; 632 state->startboard[r][c]='0';
@@ -719,7 +719,7 @@ bool load_sudoku(struct sudoku_state_t* state, char* filename)
719 return(false); 719 return(false);
720 } 720 }
721 721
722 rb->strncpy(state->filename,filename,MAX_PATH); 722 rb->strlcpy(state->filename,filename,MAX_PATH);
723 n=rb->read(fd,buf,300); 723 n=rb->read(fd,buf,300);
724 if (n <= 0) { 724 if (n <= 0) {
725 return(false); 725 return(false);
@@ -1111,7 +1111,7 @@ bool sudoku_generate(struct sudoku_state_t* state)
1111 rb->snprintf(str,sizeof(str),"Difficulty: %s",difficulty); 1111 rb->snprintf(str,sizeof(str),"Difficulty: %s",difficulty);
1112 display_board(state); 1112 display_board(state);
1113 rb->splash(HZ*3, str); 1113 rb->splash(HZ*3, str);
1114 rb->strncpy(state->filename,GAME_FILE,MAX_PATH); 1114 rb->strlcpy(state->filename,GAME_FILE,MAX_PATH);
1115 } else { 1115 } else {
1116 display_board(&new_state); 1116 display_board(&new_state);
1117 rb->splash(HZ*2, "Aborted"); 1117 rb->splash(HZ*2, "Aborted");
diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c
index a708ed7b07..c51fc4006f 100644
--- a/apps/plugins/test_codec.c
+++ b/apps/plugins/test_codec.c
@@ -451,7 +451,6 @@ static void init_ci(void)
451 451
452 /* strings and memory */ 452 /* strings and memory */
453 ci.strcpy = rb->strcpy; 453 ci.strcpy = rb->strcpy;
454 ci.strncpy = rb->strncpy;
455 ci.strlen = rb->strlen; 454 ci.strlen = rb->strlen;
456 ci.strcmp = rb->strcmp; 455 ci.strcmp = rb->strcmp;
457 ci.strcat = rb->strcat; 456 ci.strcat = rb->strcat;
@@ -716,7 +715,7 @@ enum plugin_status plugin_start(const void* parameter)
716 /* Test all files in the same directory as the file selected by the 715 /* Test all files in the same directory as the file selected by the
717 user */ 716 user */
718 717
719 rb->strncpy(dirpath,parameter,sizeof(dirpath)); 718 rb->strlcpy(dirpath,parameter,sizeof(dirpath));
720 ch = rb->strrchr(dirpath,'/'); 719 ch = rb->strrchr(dirpath,'/');
721 ch[1]=0; 720 ch[1]=0;
722 721
diff --git a/apps/plugins/text_editor.c b/apps/plugins/text_editor.c
index 703b330d6c..617aeae8b1 100644
--- a/apps/plugins/text_editor.c
+++ b/apps/plugins/text_editor.c
@@ -133,7 +133,7 @@ char *list_get_name_cb(int selected_item, void* data,
133 rb->snprintf(buf , buf_len, "%s ...", b); 133 rb->snprintf(buf , buf_len, "%s ...", b);
134 b[buf_len-10] = t; 134 b[buf_len-10] = t;
135 } 135 }
136 else rb->strncpy(buf, b, buf_len); 136 else rb->strlcpy(buf, b, buf_len);
137 return buf; 137 return buf;
138} 138}
139 139
diff --git a/apps/plugins/zxbox/snapshot.c b/apps/plugins/zxbox/snapshot.c
index d078ec78b1..9a68540a04 100644
--- a/apps/plugins/zxbox/snapshot.c
+++ b/apps/plugins/zxbox/snapshot.c
@@ -603,8 +603,7 @@ void save_snapshot_file(char *name)
603{ 603{
604 int type; 604 int type;
605 605
606 rb->strncpy(filenamebuf, name, MAXFILENAME-10); 606 rb->strlcpy(filenamebuf, name, MAXFILENAME-10 + 1);
607 filenamebuf[MAXFILENAME-10] = '\0';
608 607
609 type = SN_Z80; 608 type = SN_Z80;
610 if(check_ext(filenamebuf, "z80")) type = SN_Z80; 609 if(check_ext(filenamebuf, "z80")) type = SN_Z80;
@@ -642,8 +641,7 @@ void load_snapshot_file_type(char *name, int type)
642 int snsh; 641 int snsh;
643 SNFILE snfil; 642 SNFILE snfil;
644 643
645 rb->strncpy(filenamebuf, name, MAXFILENAME-10); 644 rb->strlcpy(filenamebuf, name, MAXFILENAME-10 + 1);
646 filenamebuf[MAXFILENAME-10] = '\0';
647 645
648 spcf_find_file_type(filenamebuf, &filetype, &type); 646 spcf_find_file_type(filenamebuf, &filetype, &type);
649 if(type < 0) type = SN_Z80; 647 if(type < 0) type = SN_Z80;
diff --git a/apps/plugins/zxbox/spconf.c b/apps/plugins/zxbox/spconf.c
index 5a14959adc..728f78638c 100644
--- a/apps/plugins/zxbox/spconf.c
+++ b/apps/plugins/zxbox/spconf.c
@@ -111,8 +111,7 @@ void spcf_read_command_line(const void* parameter)
111 111
112 file_type = extensions[ix].type; 112 file_type = extensions[ix].type;
113 file_subtype = extensions[ix].subtype; 113 file_subtype = extensions[ix].subtype;
114 rb->strncpy(filenamebuf, parameter, MAXFILENAME - 10); 114 rb->strlcpy(filenamebuf, parameter, MAXFILENAME - 10 + 1);
115 filenamebuf[MAXFILENAME-10] = '\0';
116 if(file_type < 0) file_subtype = -1; 115 if(file_type < 0) file_subtype = -1;
117 if(!spcf_find_file_type(filenamebuf, &file_type, &file_subtype)) 116 if(!spcf_find_file_type(filenamebuf, &file_type, &file_subtype))
118 return; 117 return;
diff --git a/apps/plugins/zxbox/sptape.c b/apps/plugins/zxbox/sptape.c
index f0e04de2fb..21f962ea28 100644
--- a/apps/plugins/zxbox/sptape.c
+++ b/apps/plugins/zxbox/sptape.c
@@ -594,8 +594,7 @@ void start_play_file_type(char *name, int seg, int type)
594{ 594{
595 int filetype = FT_TAPEFILE; 595 int filetype = FT_TAPEFILE;
596 596
597 rb->strncpy(tapename, name, MAXFILENAME-10); 597 rb->strlcpy(tapename, name, MAXFILENAME-10 + 1);
598 tapename[MAXFILENAME-10] = '\0';
599 598
600 currseg = seg; 599 currseg = seg;
601 tapetype = type; 600 tapetype = type;
diff --git a/apps/plugins/zxbox/tapefile.c b/apps/plugins/zxbox/tapefile.c
index 19f6aba980..0e262aa0f7 100644
--- a/apps/plugins/zxbox/tapefile.c
+++ b/apps/plugins/zxbox/tapefile.c
@@ -510,8 +510,7 @@ static int interpret_tzx_header(byte *hb, struct seginfo *csp)
510 int blen; 510 int blen;
511 rb->snprintf(seg_desc,DESC_LEN, "Begin Group: "); 511 rb->snprintf(seg_desc,DESC_LEN, "Begin Group: ");
512 blen = (int) rb->strlen(seg_desc); 512 blen = (int) rb->strlen(seg_desc);
513 rb->strncpy(seg_desc+blen, (char *) rbuf, (unsigned) csp->len); 513 rb->strlcpy(seg_desc+blen, (char *) rbuf, (unsigned) csp->len + 1);
514 seg_desc[csp->len + blen] = '\0';
515 } 514 }
516 break; 515 break;
517 516
@@ -618,8 +617,7 @@ static int interpret_tzx_header(byte *hb, struct seginfo *csp)
618 return 0; 617 return 0;
619 } 618 }
620 csp->ptr += csp->len; 619 csp->ptr += csp->len;
621 rb->strncpy(seg_desc, (char *) rbuf, (unsigned) csp->len); 620 rb->strlcpy(seg_desc, (char *) rbuf, (unsigned) csp->len + 1);
622 seg_desc[csp->len] = '\0';
623 break; 621 break;
624 622
625 case 0x32: 623 case 0x32:
diff --git a/apps/recorder/albumart.c b/apps/recorder/albumart.c
index 6bd2adade3..a378c332b3 100644
--- a/apps/recorder/albumart.c
+++ b/apps/recorder/albumart.c
@@ -66,8 +66,7 @@ static char* strip_filename(char* buf, int buf_size, const char* fullpath)
66 } 66 }
67 67
68 len = MIN(sep - fullpath + 1, buf_size - 1); 68 len = MIN(sep - fullpath + 1, buf_size - 1);
69 strncpy(buf, fullpath, len); 69 strlcpy(buf, fullpath, len + 1);
70 buf[len] = 0;
71 return (sep + 1); 70 return (sep + 1);
72} 71}
73 72
@@ -266,7 +265,7 @@ bool search_albumart_files(const struct mp3entry *id3, const char *size_string,
266 if (!found) 265 if (!found)
267 return false; 266 return false;
268 267
269 strncpy(buf, path, buflen); 268 strlcpy(buf, path, buflen);
270 logf("Album art found: %s", path); 269 logf("Album art found: %s", path);
271 return true; 270 return true;
272} 271}
diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c
index 8657aee1ba..d1dc03113d 100644
--- a/apps/recorder/pcm_record.c
+++ b/apps/recorder/pcm_record.c
@@ -529,7 +529,7 @@ static bool pcmrec_fnq_is_full(void)
529/* queue another filename - will overwrite oldest one if full */ 529/* queue another filename - will overwrite oldest one if full */
530static bool pcmrec_fnq_add_filename(const char *filename) 530static bool pcmrec_fnq_add_filename(const char *filename)
531{ 531{
532 strncpy(fn_queue + fnq_wr_pos, filename, MAX_PATH); 532 strlcpy(fn_queue + fnq_wr_pos, filename, MAX_PATH);
533 fnq_wr_pos = FNQ_NEXT(fnq_wr_pos); 533 fnq_wr_pos = FNQ_NEXT(fnq_wr_pos);
534 534
535 if (fnq_rd_pos != fnq_wr_pos) 535 if (fnq_rd_pos != fnq_wr_pos)
@@ -550,7 +550,7 @@ static bool pcmrec_fnq_replace_tail(const char *filename)
550 550
551 pos = FNQ_PREV(fnq_wr_pos); 551 pos = FNQ_PREV(fnq_wr_pos);
552 552
553 strncpy(fn_queue + pos, filename, MAX_PATH); 553 strlcpy(fn_queue + pos, filename, MAX_PATH);
554 554
555 return true; 555 return true;
556} /* pcmrec_fnq_replace_tail */ 556} /* pcmrec_fnq_replace_tail */
@@ -562,7 +562,7 @@ static bool pcmrec_fnq_get_filename(char *filename)
562 return false; 562 return false;
563 563
564 if (filename) 564 if (filename)
565 strncpy(filename, fn_queue + fnq_rd_pos, MAX_PATH); 565 strlcpy(filename, fn_queue + fnq_rd_pos, MAX_PATH);
566 566
567 fnq_rd_pos = FNQ_NEXT(fnq_rd_pos); 567 fnq_rd_pos = FNQ_NEXT(fnq_rd_pos);
568 return true; 568 return true;
@@ -976,7 +976,7 @@ static void pcmrec_new_stream(const char *filename, /* next file name */
976 bool did_flush = false; /* did a flush occurr? */ 976 bool did_flush = false; /* did a flush occurr? */
977 977
978 if (filename) 978 if (filename)
979 strncpy(path, filename, MAX_PATH); 979 strlcpy(path, filename, MAX_PATH);
980 queue_reply(&pcmrec_queue, 0); /* We have all we need */ 980 queue_reply(&pcmrec_queue, 0); /* We have all we need */
981 981
982 data.pre_chunk = NULL; 982 data.pre_chunk = NULL;
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c
index 68c45c4f01..c5729ba8b2 100644
--- a/apps/recorder/radio.c
+++ b/apps/recorder/radio.c
@@ -1138,7 +1138,7 @@ void radio_load_presets(char *filename)
1138 } 1138 }
1139 /* Temporary preset, loaded until player shuts down. */ 1139 /* Temporary preset, loaded until player shuts down. */
1140 else if(filename[0] == '/') 1140 else if(filename[0] == '/')
1141 strncpy(filepreset, filename, sizeof(filepreset)); 1141 strlcpy(filepreset, filename, sizeof(filepreset));
1142 /* Preset from default directory. */ 1142 /* Preset from default directory. */
1143 else 1143 else
1144 snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr", 1144 snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr",
@@ -1159,8 +1159,7 @@ void radio_load_presets(char *filename)
1159 { 1159 {
1160 struct fmstation * const fms = &presets[num_presets]; 1160 struct fmstation * const fms = &presets[num_presets];
1161 fms->frequency = f; 1161 fms->frequency = f;
1162 strncpy(fms->name, name, MAX_FMPRESET_LEN); 1162 strlcpy(fms->name, name, MAX_FMPRESET_LEN+1);
1163 fms->name[MAX_FMPRESET_LEN] = '\0';
1164 num_presets++; 1163 num_presets++;
1165 } 1164 }
1166 } 1165 }
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index d7ab9c795c..0a890d03da 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -964,7 +964,7 @@ static char * reclist_get_name(int selected_item, void * data,
964 } 964 }
965 else 965 else
966 { 966 {
967 strncpy(buffer, str(LANG_RECORDING_FILENAME), buffer_len); 967 strlcpy(buffer, str(LANG_RECORDING_FILENAME), buffer_len);
968 } 968 }
969 break; 969 break;
970 } 970 }
diff --git a/apps/replaygain.c b/apps/replaygain.c
index b398afc294..bcdbffec5c 100644
--- a/apps/replaygain.c
+++ b/apps/replaygain.c
@@ -218,8 +218,7 @@ long parse_replaygain(const char* key, const char* value,
218 /* A few characters just isn't interesting... */ 218 /* A few characters just isn't interesting... */
219 if (len > 1) 219 if (len > 1)
220 { 220 {
221 strncpy(buffer, value, len); 221 strlcpy(buffer, value, len + 1);
222 buffer[len] = 0;
223 *p = buffer; 222 *p = buffer;
224 return len + 1; 223 return len + 1;
225 } 224 }
diff --git a/apps/root_menu.c b/apps/root_menu.c
index 39d3fbe7ab..15bc524cce 100644
--- a/apps/root_menu.c
+++ b/apps/root_menu.c
@@ -77,7 +77,7 @@ static char current_track_path[MAX_PATH];
77static void rootmenu_track_changed_callback(void* param) 77static void rootmenu_track_changed_callback(void* param)
78{ 78{
79 struct mp3entry *id3 = (struct mp3entry *)param; 79 struct mp3entry *id3 = (struct mp3entry *)param;
80 strncpy(current_track_path, id3->path, MAX_PATH); 80 strlcpy(current_track_path, id3->path, MAX_PATH);
81} 81}
82static int browser(void* param) 82static int browser(void* param)
83{ 83{
@@ -202,7 +202,7 @@ static int browser(void* param)
202#endif 202#endif
203 case GO_TO_BROWSEPLUGINS: 203 case GO_TO_BROWSEPLUGINS:
204 filter = SHOW_PLUGINS; 204 filter = SHOW_PLUGINS;
205 strncpy(folder, PLUGIN_DIR, MAX_PATH); 205 strlcpy(folder, PLUGIN_DIR, MAX_PATH);
206 break; 206 break;
207 } 207 }
208 ret_val = rockbox_browse(folder, filter); 208 ret_val = rockbox_browse(folder, filter);
diff --git a/apps/settings.c b/apps/settings.c
index e2f40a1f44..29360f14d3 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -246,8 +246,7 @@ static bool cfg_string_to_int(int setting_id, int* out, const char* str)
246 } 246 }
247 else return false; 247 else return false;
248 } 248 }
249 strncpy(temp, start, end-start); 249 strlcpy(temp, start, end-start+1);
250 temp[end-start] = '\0';
251 if (!strcmp(str, temp)) 250 if (!strcmp(str, temp))
252 { 251 {
253 *out = count; 252 *out = count;
@@ -331,20 +330,18 @@ bool settings_load_config(const char* file, bool apply)
331 settings[i].filename_setting->prefix, 330 settings[i].filename_setting->prefix,
332 len)) 331 len))
333 { 332 {
334 strncpy(storage,&value[len],MAX_PATH); 333 strlcpy(storage, &value[len], MAX_PATH);
335 } 334 }
336 else strncpy(storage,value,MAX_PATH); 335 else strlcpy(storage, value, MAX_PATH);
337 } 336 }
338 else strncpy(storage,value,MAX_PATH); 337 else strlcpy(storage, value, MAX_PATH);
339 if (settings[i].filename_setting->suffix) 338 if (settings[i].filename_setting->suffix)
340 { 339 {
341 char *s = strcasestr(storage,settings[i].filename_setting->suffix); 340 char *s = strcasestr(storage,settings[i].filename_setting->suffix);
342 if (s) *s = '\0'; 341 if (s) *s = '\0';
343 } 342 }
344 strncpy((char*)settings[i].setting,storage, 343 strlcpy((char*)settings[i].setting, storage,
345 settings[i].filename_setting->max_len); 344 settings[i].filename_setting->max_len);
346 ((char*)settings[i].setting)
347 [settings[i].filename_setting->max_len-1] = '\0';
348 break; 345 break;
349 } 346 }
350 } 347 }
@@ -379,12 +376,11 @@ bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len)
379 if (value[count] == val) 376 if (value[count] == val)
380 { 377 {
381 if (end == NULL) 378 if (end == NULL)
382 strncpy(buf, start, buf_len); 379 strlcpy(buf, start, buf_len);
383 else 380 else
384 { 381 {
385 int len = (buf_len > (end-start))? end-start: buf_len; 382 int len = (buf_len > (end-start))? end-start: buf_len;
386 strncpy(buf, start, len); 383 strlcpy(buf, start, len+1);
387 buf[len] = '\0';
388 } 384 }
389 return true; 385 return true;
390 } 386 }
@@ -408,12 +404,11 @@ bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len)
408 } 404 }
409 end = strchr(start,','); 405 end = strchr(start,',');
410 if (end == NULL) 406 if (end == NULL)
411 strncpy(buf, start, buf_len); 407 strlcpy(buf, start, buf_len);
412 else 408 else
413 { 409 {
414 int len = (buf_len > (end-start))? end-start: buf_len; 410 int len = (buf_len > (end-start))? end-start: buf_len;
415 strncpy(buf, start, len); 411 strlcpy(buf, start, len+1);
416 buf[len] = '\0';
417 } 412 }
418 return true; 413 return true;
419} 414}
@@ -468,7 +463,7 @@ bool cfg_to_string(int i/*setting_id*/, char* buf, int buf_len)
468 (char*)settings[i].setting, 463 (char*)settings[i].setting,
469 settings[i].filename_setting->suffix); 464 settings[i].filename_setting->suffix);
470 } 465 }
471 else strncpy(buf,(char*)settings[i].setting, 466 else strlcpy(buf,(char*)settings[i].setting,
472 settings[i].filename_setting->max_len); 467 settings[i].filename_setting->max_len);
473 break; 468 break;
474 } /* switch () */ 469 } /* switch () */
@@ -1011,7 +1006,7 @@ void reset_setting(const struct settings_list *setting, void *var)
1011 break; 1006 break;
1012 case F_T_CHARPTR: 1007 case F_T_CHARPTR:
1013 case F_T_UCHARPTR: 1008 case F_T_UCHARPTR:
1014 strncpy((char*)var, setting->default_val.charptr, 1009 strlcpy((char*)var, setting->default_val.charptr,
1015 setting->filename_setting->max_len); 1010 setting->filename_setting->max_len);
1016 break; 1011 break;
1017 } 1012 }
@@ -1114,7 +1109,7 @@ static void set_option_formatter(char* buf, size_t size, int item, const char* u
1114{ 1109{
1115 (void)unit; 1110 (void)unit;
1116 const unsigned char *text = set_option_options[item].string; 1111 const unsigned char *text = set_option_options[item].string;
1117 strncpy(buf, P2STR(text), size); 1112 strlcpy(buf, P2STR(text), size);
1118} 1113}
1119static int32_t set_option_get_talk_id(int value, int unit) 1114static int32_t set_option_get_talk_id(int value, int unit)
1120{ 1115{
@@ -1173,12 +1168,11 @@ void set_file(const char* filename, char* setting, int maxlen)
1173 } 1168 }
1174 if(ptr == fptr) extlen = 0; 1169 if(ptr == fptr) extlen = 0;
1175 1170
1176 if (strncasecmp(ROCKBOX_DIR, filename ,strlen(ROCKBOX_DIR)) || 1171 if (strncasecmp(ROCKBOX_DIR, filename, strlen(ROCKBOX_DIR)) ||
1177 (len-extlen > maxlen)) 1172 (len-extlen > maxlen))
1178 return; 1173 return;
1179 1174
1180 strncpy(setting, fptr, len-extlen); 1175 strlcpy(setting, fptr, len-extlen+1);
1181 setting[len-extlen]=0;
1182 1176
1183 settings_save(); 1177 settings_save();
1184} 1178}
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 61874787b9..c39ab580fc 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -439,7 +439,7 @@ static void qs_load_from_cfg(void* var, char*value)
439static char* qs_write_to_cfg(void* setting, char*buf, int buf_len) 439static char* qs_write_to_cfg(void* setting, char*buf, int buf_len)
440{ 440{
441 const struct settings_list *var = &settings[*(int*)setting]; 441 const struct settings_list *var = &settings[*(int*)setting];
442 strncpy(buf, var->cfg_name, buf_len); 442 strlcpy(buf, var->cfg_name, buf_len);
443 return buf; 443 return buf;
444} 444}
445static bool qs_is_changed(void* setting, void* defaultval) 445static bool qs_is_changed(void* setting, void* defaultval)
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 07af9bf833..4d4935a6b6 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -706,7 +706,7 @@ static bool retrieve(struct tagcache_search *tcs, struct index_entry *idx,
706 if (tag != tag_filename) 706 if (tag != tag_filename)
707 { 707 {
708 ep = (struct tagfile_entry *)&hdr->tags[tag][seek]; 708 ep = (struct tagfile_entry *)&hdr->tags[tag][seek];
709 strncpy(buf, ep->tag_data, size-1); 709 strlcpy(buf, ep->tag_data, size);
710 710
711 return true; 711 return true;
712 } 712 }
diff --git a/apps/tagtree.c b/apps/tagtree.c
index 691b2273de..5d61589eab 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -593,7 +593,7 @@ static bool parse_search(struct menu_entry *entry, const char *str)
593 menus[menu_count] = buffer_alloc(sizeof(struct menu_root)); 593 menus[menu_count] = buffer_alloc(sizeof(struct menu_root));
594 new_menu = menus[menu_count]; 594 new_menu = menus[menu_count];
595 memset(new_menu, 0, sizeof(struct menu_root)); 595 memset(new_menu, 0, sizeof(struct menu_root));
596 strncpy(new_menu->id, buf, MAX_MENU_ID_SIZE-1); 596 strlcpy(new_menu->id, buf, MAX_MENU_ID_SIZE);
597 entry->link = menu_count; 597 entry->link = menu_count;
598 ++menu_count; 598 ++menu_count;
599 599
@@ -839,7 +839,7 @@ static int parse_line(int n, const char *buf, void *parameters)
839 menu = menus[menu_count]; 839 menu = menus[menu_count];
840 ++menu_count; 840 ++menu_count;
841 memset(menu, 0, sizeof(struct menu_root)); 841 memset(menu, 0, sizeof(struct menu_root));
842 strncpy(menu->id, data, MAX_MENU_ID_SIZE-1); 842 strlcpy(menu->id, data, MAX_MENU_ID_SIZE);
843 } 843 }
844 844
845 if (get_token_str(menu->title, sizeof(menu->title)) < 0) 845 if (get_token_str(menu->title, sizeof(menu->title)) < 0)
@@ -1442,8 +1442,8 @@ int tagtree_enter(struct tree_context* c)
1442 csi = menu->items[seek]->si; 1442 csi = menu->items[seek]->si;
1443 c->currextra = 0; 1443 c->currextra = 0;
1444 1444
1445 strncpy(current_title[c->currextra], dptr->name, 1445 strlcpy(current_title[c->currextra], dptr->name,
1446 sizeof(current_title[0]) - 1); 1446 sizeof(current_title[0]));
1447 1447
1448 /* Read input as necessary. */ 1448 /* Read input as necessary. */
1449 for (i = 0; i < csi->tagorder_count; i++) 1449 for (i = 0; i < csi->tagorder_count; i++)
@@ -1464,7 +1464,7 @@ int tagtree_enter(struct tree_context* c)
1464 if (source == source_current_path && id3) 1464 if (source == source_current_path && id3)
1465 { 1465 {
1466 char *e; 1466 char *e;
1467 strncpy(searchstring, id3->path, SEARCHSTR_SIZE); 1467 strlcpy(searchstring, id3->path, SEARCHSTR_SIZE);
1468 e = strrchr(searchstring, '/'); 1468 e = strrchr(searchstring, '/');
1469 if (e) 1469 if (e)
1470 *e = '\0'; 1470 *e = '\0';
@@ -1477,8 +1477,7 @@ int tagtree_enter(struct tree_context* c)
1477 char **src = (char**)((char*)id3 + offset); 1477 char **src = (char**)((char*)id3 + offset);
1478 if (*src) 1478 if (*src)
1479 { 1479 {
1480 strncpy(searchstring, *src, SEARCHSTR_SIZE); 1480 strlcpy(searchstring, *src, SEARCHSTR_SIZE);
1481 searchstring[SEARCHSTR_SIZE-1] = '\0';
1482 } 1481 }
1483 } 1482 }
1484 else 1483 else
@@ -1528,8 +1527,8 @@ int tagtree_enter(struct tree_context* c)
1528 c->dirlevel--; 1527 c->dirlevel--;
1529 1528
1530 /* Update the statusbar title */ 1529 /* Update the statusbar title */
1531 strncpy(current_title[c->currextra], dptr->name, 1530 strlcpy(current_title[c->currextra], dptr->name,
1532 sizeof(current_title[0]) - 1); 1531 sizeof(current_title[0]));
1533 break; 1532 break;
1534 1533
1535 default: 1534 default:
diff --git a/apps/talk.c b/apps/talk.c
index 73c26073b7..b2e25e1f8f 100644
--- a/apps/talk.c
+++ b/apps/talk.c
@@ -533,7 +533,7 @@ void talk_init(void)
533#endif /* CONFIG_CODEC == SWCODEC */ 533#endif /* CONFIG_CODEC == SWCODEC */
534 534
535 talk_initialized = true; 535 talk_initialized = true;
536 strncpy((char *) last_lang, (char *)global_settings.lang_file, 536 strlcpy((char *)last_lang, (char *)global_settings.lang_file,
537 MAX_FILENAME); 537 MAX_FILENAME);
538 538
539#if CONFIG_CODEC == SWCODEC 539#if CONFIG_CODEC == SWCODEC
@@ -755,7 +755,7 @@ static int talk_spell_basename(const char *path,
755 } 755 }
756 char buf[MAX_PATH]; 756 char buf[MAX_PATH];
757 /* Spell only the path component after the last slash */ 757 /* Spell only the path component after the last slash */
758 strncpy(buf, path, MAX_PATH); 758 strlcpy(buf, path, sizeof(buf));
759 if(strlen(buf) >1 && buf[strlen(buf)-1] == '/') 759 if(strlen(buf) >1 && buf[strlen(buf)-1] == '/')
760 /* strip trailing slash */ 760 /* strip trailing slash */
761 buf[strlen(buf)-1] = '\0'; 761 buf[strlen(buf)-1] = '\0';
diff --git a/apps/tree.c b/apps/tree.c
index ef65c6d86c..576453a3ad 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -505,7 +505,7 @@ char *getcwd(char *buf, int size)
505 return tc.currdir; 505 return tc.currdir;
506 else if (size > 0) 506 else if (size > 0)
507 { 507 {
508 strncpy(buf, tc.currdir, size); 508 strlcpy(buf, tc.currdir, size);
509 return buf; 509 return buf;
510 } 510 }
511 else 511 else
@@ -924,7 +924,7 @@ int rockbox_browse(const char *root, int dirfilter)
924 } 924 }
925 else 925 else
926 { 926 {
927 strncpy(current, LANG_DIR "/english.lng", sizeof(current)); 927 strlcpy(current, LANG_DIR "/english.lng", sizeof(current));
928 } 928 }
929 } 929 }
930 /* Center on currently loaded WPS */ 930 /* Center on currently loaded WPS */
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 50c57e3323..8e1cef31e0 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -52,7 +52,7 @@ common/strcmp.c
52common/strnatcmp.c 52common/strnatcmp.c
53common/strcpy.c 53common/strcpy.c
54common/strncmp.c 54common/strncmp.c
55common/strncpy.c 55common/strlcpy.c
56common/strrchr.c 56common/strrchr.c
57common/strtok.c 57common/strtok.c
58common/strstr.c 58common/strstr.c
diff --git a/firmware/common/dir_uncached.c b/firmware/common/dir_uncached.c
index c6af145930..25677a0903 100644
--- a/firmware/common/dir_uncached.c
+++ b/firmware/common/dir_uncached.c
@@ -58,8 +58,7 @@ int strip_volume(const char* name, char* namecopy)
58 name = "/"; /* else this must be the root dir */ 58 name = "/"; /* else this must be the root dir */
59 } 59 }
60 60
61 strncpy(namecopy, name, MAX_PATH); 61 strlcpy(namecopy, name, MAX_PATH);
62 namecopy[MAX_PATH-1] = '\0';
63 62
64 return volume; 63 return volume;
65} 64}
@@ -120,8 +119,7 @@ DIR_UNCACHED* opendir_uncached(const char* name)
120 volume = strip_volume(name, namecopy); 119 volume = strip_volume(name, namecopy);
121 pdir->volumecounter = 0; 120 pdir->volumecounter = 0;
122#else 121#else
123 strncpy(namecopy,name,sizeof(namecopy)); /* just copy */ 122 strlcpy(namecopy, name, sizeof(namecopy)); /* just copy */
124 namecopy[sizeof(namecopy)-1] = '\0';
125#endif 123#endif
126 124
127 if ( fat_opendir(IF_MV2(volume,) &pdir->fatdir, 0, NULL) < 0 ) { 125 if ( fat_opendir(IF_MV2(volume,) &pdir->fatdir, 0, NULL) < 0 ) {
@@ -204,7 +202,7 @@ struct dirent_uncached* readdir_uncached(DIR_UNCACHED* dir)
204 if ( !entry.name[0] ) 202 if ( !entry.name[0] )
205 return NULL; 203 return NULL;
206 204
207 strncpy(theent->d_name, entry.name, sizeof( theent->d_name ) ); 205 strlcpy(theent->d_name, entry.name, sizeof(theent->d_name));
208 theent->attribute = entry.attr; 206 theent->attribute = entry.attr;
209 theent->size = entry.filesize; 207 theent->size = entry.filesize;
210 theent->startcluster = entry.firstcluster; 208 theent->startcluster = entry.firstcluster;
@@ -230,8 +228,7 @@ int mkdir_uncached(const char *name)
230 return -1; 228 return -1;
231 } 229 }
232 230
233 strncpy(namecopy,name,sizeof(namecopy)); 231 strlcpy(namecopy, name, sizeof(namecopy));
234 namecopy[sizeof(namecopy)-1] = 0;
235 232
236 /* Split the base name and the path */ 233 /* Split the base name and the path */
237 end = strrchr(namecopy, '/'); 234 end = strrchr(namecopy, '/');
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 01ed72adc1..e846d55452 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -232,11 +232,11 @@ static int dircache_scan(IF_MV2(int volume,) struct travel_data *td)
232 return -2; 232 return -2;
233 233
234 td->pathpos = strlen(dircache_cur_path); 234 td->pathpos = strlen(dircache_cur_path);
235 strncpy(&dircache_cur_path[td->pathpos], "/", 235 strlcpy(&dircache_cur_path[td->pathpos], "/",
236 sizeof(dircache_cur_path) - td->pathpos - 1); 236 sizeof(dircache_cur_path) - td->pathpos);
237#ifdef SIMULATOR 237#ifdef SIMULATOR
238 strncpy(&dircache_cur_path[td->pathpos+1], td->entry->d_name, 238 strlcpy(&dircache_cur_path[td->pathpos+1], td->entry->d_name,
239 sizeof(dircache_cur_path) - td->pathpos - 2); 239 sizeof(dircache_cur_path) - td->pathpos - 1);
240 240
241 td->newdir = opendir_uncached(dircache_cur_path); 241 td->newdir = opendir_uncached(dircache_cur_path);
242 if (td->newdir == NULL) 242 if (td->newdir == NULL)
@@ -245,8 +245,8 @@ static int dircache_scan(IF_MV2(int volume,) struct travel_data *td)
245 return -3; 245 return -3;
246 } 246 }
247#else 247#else
248 strncpy(&dircache_cur_path[td->pathpos+1], td->entry.name, 248 strlcpy(&dircache_cur_path[td->pathpos+1], td->entry.name,
249 sizeof(dircache_cur_path) - td->pathpos - 2); 249 sizeof(dircache_cur_path) - td->pathpos - 1);
250 250
251 td->newdir = *td->dir; 251 td->newdir = *td->dir;
252 if (fat_opendir(IF_MV2(volume,) &td->newdir, 252 if (fat_opendir(IF_MV2(volume,) &td->newdir,
@@ -399,7 +399,7 @@ static struct dircache_entry* dircache_get_entry(const char *path,
399 char* part; 399 char* part;
400 char* end; 400 char* end;
401 401
402 strncpy(namecopy, path, sizeof(namecopy) - 1); 402 strlcpy(namecopy, path, sizeof(namecopy));
403 cache_entry = dircache_root; 403 cache_entry = dircache_root;
404 before = NULL; 404 before = NULL;
405 405
@@ -926,7 +926,7 @@ static struct dircache_entry* dircache_new_entry(const char *path, int attribute
926 char *new; 926 char *new;
927 long last_cache_size = dircache_size; 927 long last_cache_size = dircache_size;
928 928
929 strncpy(basedir, path, sizeof(basedir)-1); 929 strlcpy(basedir, path, sizeof(basedir));
930 new = strrchr(basedir, '/'); 930 new = strrchr(basedir, '/');
931 if (new == NULL) 931 if (new == NULL)
932 { 932 {
@@ -997,8 +997,8 @@ void dircache_bind(int fd, const char *path)
997 { 997 {
998 if (fdbind_idx >= MAX_PENDING_BINDINGS) 998 if (fdbind_idx >= MAX_PENDING_BINDINGS)
999 return ; 999 return ;
1000 strncpy(fdbind_cache[fdbind_idx].path, path, 1000 strlcpy(fdbind_cache[fdbind_idx].path, path,
1001 sizeof(fdbind_cache[fdbind_idx].path)-1); 1001 sizeof(fdbind_cache[fdbind_idx].path));
1002 fdbind_cache[fdbind_idx].fd = fd; 1002 fdbind_cache[fdbind_idx].fd = fd;
1003 fdbind_idx++; 1003 fdbind_idx++;
1004 return ; 1004 return ;
@@ -1141,7 +1141,7 @@ void dircache_rename(const char *oldpath, const char *newpath)
1141 /* Generate the absolute path for destination if necessary. */ 1141 /* Generate the absolute path for destination if necessary. */
1142 if (newpath[0] != '/') 1142 if (newpath[0] != '/')
1143 { 1143 {
1144 strncpy(absolute_path, oldpath, sizeof(absolute_path)-1); 1144 strlcpy(absolute_path, oldpath, sizeof(absolute_path));
1145 p = strrchr(absolute_path, '/'); 1145 p = strrchr(absolute_path, '/');
1146 if (!p) 1146 if (!p)
1147 { 1147 {
@@ -1151,7 +1151,7 @@ void dircache_rename(const char *oldpath, const char *newpath)
1151 } 1151 }
1152 1152
1153 *p = '\0'; 1153 *p = '\0';
1154 strncpy(p, absolute_path, sizeof(absolute_path)-1-strlen(p)); 1154 strlcpy(p, absolute_path, sizeof(absolute_path)-strlen(p));
1155 newpath = absolute_path; 1155 newpath = absolute_path;
1156 } 1156 }
1157 1157
@@ -1246,7 +1246,7 @@ struct dircache_entry* readdir_cached(DIR_CACHED* dir)
1246 if (regentry == NULL) 1246 if (regentry == NULL)
1247 return NULL; 1247 return NULL;
1248 1248
1249 strncpy(dir->secondary_entry.d_name, regentry->d_name, MAX_PATH-1); 1249 strlcpy(dir->secondary_entry.d_name, regentry->d_name, MAX_PATH);
1250 dir->secondary_entry.size = regentry->size; 1250 dir->secondary_entry.size = regentry->size;
1251 dir->secondary_entry.startcluster = regentry->startcluster; 1251 dir->secondary_entry.startcluster = regentry->startcluster;
1252 dir->secondary_entry.attribute = regentry->attribute; 1252 dir->secondary_entry.attribute = regentry->attribute;
@@ -1268,7 +1268,7 @@ struct dircache_entry* readdir_cached(DIR_CACHED* dir)
1268 1268
1269 dir->entry = ce->next; 1269 dir->entry = ce->next;
1270 1270
1271 strncpy(dir->secondary_entry.d_name, ce->d_name, MAX_PATH-1); 1271 strlcpy(dir->secondary_entry.d_name, ce->d_name, MAX_PATH);
1272 /* Can't do `dir->secondary_entry = *ce` 1272 /* Can't do `dir->secondary_entry = *ce`
1273 because that modifies the d_name pointer. */ 1273 because that modifies the d_name pointer. */
1274 dir->secondary_entry.size = ce->size; 1274 dir->secondary_entry.size = ce->size;
diff --git a/firmware/common/file.c b/firmware/common/file.c
index 7c01f03817..3d7722f687 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -132,8 +132,7 @@ static int open_internal(const char* pathname, int flags, bool use_cache)
132 } 132 }
133#endif 133#endif
134 134
135 strncpy(pathnamecopy,pathname,sizeof(pathnamecopy)); 135 strlcpy(pathnamecopy, pathname, sizeof(pathnamecopy));
136 pathnamecopy[sizeof(pathnamecopy)-1] = 0;
137 136
138 /* locate filename */ 137 /* locate filename */
139 name=strrchr(pathnamecopy+1,'/'); 138 name=strrchr(pathnamecopy+1,'/');
diff --git a/firmware/common/strlcpy.c b/firmware/common/strlcpy.c
new file mode 100644
index 0000000000..ac30ef01fe
--- /dev/null
+++ b/firmware/common/strlcpy.c
@@ -0,0 +1,52 @@
1/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <string.h>
21
22/*
23 * Copy src to string dst of size siz. At most siz-1 characters
24 * will be copied. Always NUL terminates (unless siz == 0).
25 * Returns strlen(src); if retval >= siz, truncation occurred.
26 */
27size_t
28strlcpy(char *dst, const char *src, size_t siz)
29{
30 char *d = dst;
31 const char *s = src;
32 size_t n = siz;
33
34 /* Copy as many bytes as will fit */
35 if (n != 0) {
36 while (--n != 0) {
37 if ((*d++ = *s++) == '\0')
38 break;
39 }
40 }
41
42 /* Not enough room in dst, add NUL and traverse rest of src */
43 if (n == 0) {
44 if (siz != 0)
45 *d = '\0'; /* NUL-terminate dst */
46 while (*s++)
47 ;
48 }
49
50 return(s - src - 1); /* count does not include NUL */
51}
52
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 2ff4c61ac4..a710593a69 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -1183,7 +1183,7 @@ static int write_long_name(struct fat_file* file,
1183 /* shortname entry */ 1183 /* shortname entry */
1184 unsigned short date=0, time=0, tenth=0; 1184 unsigned short date=0, time=0, tenth=0;
1185 LDEBUGF("Shortname entry: %s\n", shortname); 1185 LDEBUGF("Shortname entry: %s\n", shortname);
1186 strncpy(entry + FATDIR_NAME, shortname, 11); 1186 memcpy(entry + FATDIR_NAME, shortname, 11);
1187 entry[FATDIR_ATTR] = is_directory?FAT_ATTR_DIRECTORY:0; 1187 entry[FATDIR_ATTR] = is_directory?FAT_ATTR_DIRECTORY:0;
1188 entry[FATDIR_NTRES] = 0; 1188 entry[FATDIR_NTRES] = 0;
1189 1189
@@ -1271,7 +1271,7 @@ static int add_dir_entry(struct fat_dir* dir,
1271 /* The "." and ".." directory entries must not be long names */ 1271 /* The "." and ".." directory entries must not be long names */
1272 if(dotdir) { 1272 if(dotdir) {
1273 int i; 1273 int i;
1274 strncpy(shortname, name, 12); 1274 strlcpy(shortname, name, 12);
1275 for(i = strlen(shortname); i < 12; i++) 1275 for(i = strlen(shortname); i < 12; i++)
1276 shortname[i] = ' '; 1276 shortname[i] = ' ';
1277 1277
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index ef0865fc8c..882bfa0854 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -1152,7 +1152,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
1152 } 1152 }
1153 1153
1154 end = strchr(s->line, '\0'); 1154 end = strchr(s->line, '\0');
1155 strncpy(end, string, current_vp->width/2); 1155 strlcpy(end, string, current_vp->width/2);
1156 1156
1157 s->vp = current_vp; 1157 s->vp = current_vp;
1158 s->y = y; 1158 s->y = y;
diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c
index 5fb652431c..f11fd6fdf9 100644
--- a/firmware/drivers/lcd-1bit-vert.c
+++ b/firmware/drivers/lcd-1bit-vert.c
@@ -845,7 +845,7 @@ void LCDFN(puts_scroll_style_offset)(int x, int y, const unsigned char *string,
845 } 845 }
846 846
847 end = strchr(s->line, '\0'); 847 end = strchr(s->line, '\0');
848 strncpy(end, string, current_vp->width/2); 848 strlcpy(end, string, current_vp->width/2);
849 849
850 s->vp = current_vp; 850 s->vp = current_vp;
851 s->y = y; 851 s->y = y;
diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c
index 801927eb37..57d27d2ead 100644
--- a/firmware/drivers/lcd-2bit-vert.c
+++ b/firmware/drivers/lcd-2bit-vert.c
@@ -1154,7 +1154,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
1154 } 1154 }
1155 1155
1156 end = strchr(s->line, '\0'); 1156 end = strchr(s->line, '\0');
1157 strncpy(end, (char *)string, current_vp->width/2); 1157 strlcpy(end, (char *)string, current_vp->width/2);
1158 1158
1159 s->vp = current_vp; 1159 s->vp = current_vp;
1160 s->y = y; 1160 s->y = y;
diff --git a/firmware/drivers/lcd-2bit-vi.c b/firmware/drivers/lcd-2bit-vi.c
index 1c0a717d13..0a73f0dd25 100644
--- a/firmware/drivers/lcd-2bit-vi.c
+++ b/firmware/drivers/lcd-2bit-vi.c
@@ -1167,7 +1167,7 @@ void LCDFN(puts_scroll_style_offset)(int x, int y, const unsigned char *string,
1167 } 1167 }
1168 1168
1169 end = strchr(s->line, '\0'); 1169 end = strchr(s->line, '\0');
1170 strncpy(end, (char *)string, current_vp->width/2); 1170 strlcpy(end, (char *)string, current_vp->width/2);
1171 1171
1172 s->vp = current_vp; 1172 s->vp = current_vp;
1173 s->y = y; 1173 s->y = y;
diff --git a/firmware/drivers/lcd-charcell.c b/firmware/drivers/lcd-charcell.c
index ca5809899f..33337daf19 100644
--- a/firmware/drivers/lcd-charcell.c
+++ b/firmware/drivers/lcd-charcell.c
@@ -496,7 +496,7 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
496 } 496 }
497 497
498 end = strchr(s->line, '\0'); 498 end = strchr(s->line, '\0');
499 strncpy(end, string, utf8seek(s->line, current_vp->width)); 499 strlcpy(end, string, utf8seek(s->line, current_vp->width));
500 500
501 s->vp = current_vp; 501 s->vp = current_vp;
502 s->y = y; 502 s->y = y;
diff --git a/firmware/general.c b/firmware/general.c
index 14b2b55bf9..6f7238ead1 100644
--- a/firmware/general.c
+++ b/firmware/general.c
@@ -110,7 +110,7 @@ char *create_numbered_filename(char *buffer, const char *path,
110 char fmtstring[12]; 110 char fmtstring[12];
111 111
112 if (buffer != path) 112 if (buffer != path)
113 strncpy(buffer, path, MAX_PATH); 113 strlcpy(buffer, path, MAX_PATH);
114 114
115 pathlen = strlen(buffer); 115 pathlen = strlen(buffer);
116 116
@@ -185,7 +185,7 @@ char *create_datetime_filename(char *buffer, const char *path,
185 last_tm = *tm; 185 last_tm = *tm;
186 186
187 if (buffer != path) 187 if (buffer != path)
188 strncpy(buffer, path, MAX_PATH); 188 strlcpy(buffer, path, MAX_PATH);
189 189
190 pathlen = strlen(buffer); 190 pathlen = strlen(buffer);
191 snprintf(buffer + pathlen, MAX_PATH - pathlen, 191 snprintf(buffer + pathlen, MAX_PATH - pathlen,
diff --git a/firmware/include/string.h b/firmware/include/string.h
index 32b86cd2b0..6085c10eb6 100644
--- a/firmware/include/string.h
+++ b/firmware/include/string.h
@@ -35,13 +35,14 @@ char *_EXFUN(strerror,(int));
35size_t _EXFUN(strlen,(const char *)); 35size_t _EXFUN(strlen,(const char *));
36char *_EXFUN(strncat,(char *, const char *, size_t)); 36char *_EXFUN(strncat,(char *, const char *, size_t));
37int _EXFUN(strncmp,(const char *, const char *, size_t)); 37int _EXFUN(strncmp,(const char *, const char *, size_t));
38char *_EXFUN(strncpy,(char *, const char *, size_t));
39char *_EXFUN(strpbrk,(const char *, const char *)); 38char *_EXFUN(strpbrk,(const char *, const char *));
40char *_EXFUN(strrchr,(const char *, int)); 39char *_EXFUN(strrchr,(const char *, int));
41size_t _EXFUN(strspn,(const char *, const char *)); 40size_t _EXFUN(strspn,(const char *, const char *));
42char *_EXFUN(strstr,(const char *, const char *)); 41char *_EXFUN(strstr,(const char *, const char *));
43char *_EXFUN(strcasestr,(const char *, const char *)); 42char *_EXFUN(strcasestr,(const char *, const char *));
44 43
44size_t strlcpy(char *dst, const char *src, size_t siz);
45
45#ifndef _REENT_ONLY 46#ifndef _REENT_ONLY
46char *_EXFUN(strtok,(char *, const char *)); 47char *_EXFUN(strtok,(char *, const char *));
47#endif 48#endif
diff --git a/firmware/logf.c b/firmware/logf.c
index a704ad2d67..6e3e532450 100644
--- a/firmware/logf.c
+++ b/firmware/logf.c
@@ -145,7 +145,7 @@ void _logf(const char *format, ...)
145 while(len > MAX_LOGF_ENTRY) 145 while(len > MAX_LOGF_ENTRY)
146 { 146 {
147 ptr = logfbuffer[logfindex]; 147 ptr = logfbuffer[logfindex];
148 strncpy(ptr, buf + tlen, MAX_LOGF_ENTRY-1); 148 strlcpy(ptr, buf + tlen, MAX_LOGF_ENTRY);
149 ptr[MAX_LOGF_ENTRY] = LOGF_TERMINATE_CONTINUE_LINE; 149 ptr[MAX_LOGF_ENTRY] = LOGF_TERMINATE_CONTINUE_LINE;
150 logfindex++; 150 logfindex++;
151 check_logfindex(); 151 check_logfindex();