1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * PROJECT: ReactOS CRT library
3*c2c66affSColin Finck * LICENSE: See COPYING in the top level directory
4*c2c66affSColin Finck * FILE: lib/sdk/crt/stdlib/makepath_s.c
5*c2c66affSColin Finck * PURPOSE: Creates a path
6*c2c66affSColin Finck * PROGRAMMERS: Wine team
7*c2c66affSColin Finck * Copyright 1996,1998 Marcus Meissner
8*c2c66affSColin Finck * Copyright 1996 Jukka Iivonen
9*c2c66affSColin Finck * Copyright 1997,2000 Uwe Bonnes
10*c2c66affSColin Finck * Copyright 2000 Jon Griffiths
11*c2c66affSColin Finck *
12*c2c66affSColin Finck */
13*c2c66affSColin Finck
14*c2c66affSColin Finck #include <precomp.h>
15*c2c66affSColin Finck #include <stdlib.h>
16*c2c66affSColin Finck #include <string.h>
17*c2c66affSColin Finck
18*c2c66affSColin Finck /*********************************************************************
19*c2c66affSColin Finck * _makepath_s (MSVCRT.@)
20*c2c66affSColin Finck *
21*c2c66affSColin Finck * Safe version of _makepath.
22*c2c66affSColin Finck */
_makepath_s(char * path,size_t size,const char * drive,const char * directory,const char * filename,const char * extension)23*c2c66affSColin Finck int CDECL _makepath_s(char *path, size_t size, const char *drive,
24*c2c66affSColin Finck const char *directory, const char *filename,
25*c2c66affSColin Finck const char *extension)
26*c2c66affSColin Finck {
27*c2c66affSColin Finck char *p = path;
28*c2c66affSColin Finck
29*c2c66affSColin Finck if (!path || !size)
30*c2c66affSColin Finck {
31*c2c66affSColin Finck *_errno() = EINVAL;
32*c2c66affSColin Finck return EINVAL;
33*c2c66affSColin Finck }
34*c2c66affSColin Finck
35*c2c66affSColin Finck if (drive && drive[0])
36*c2c66affSColin Finck {
37*c2c66affSColin Finck if (size <= 2)
38*c2c66affSColin Finck goto range;
39*c2c66affSColin Finck
40*c2c66affSColin Finck *p++ = drive[0];
41*c2c66affSColin Finck *p++ = ':';
42*c2c66affSColin Finck size -= 2;
43*c2c66affSColin Finck }
44*c2c66affSColin Finck
45*c2c66affSColin Finck if (directory && directory[0])
46*c2c66affSColin Finck {
47*c2c66affSColin Finck size_t len = strlen(directory);
48*c2c66affSColin Finck unsigned int needs_separator = directory[len - 1] != '/' && directory[len - 1] != '\\';
49*c2c66affSColin Finck size_t copylen = min(size - 1, len);
50*c2c66affSColin Finck
51*c2c66affSColin Finck if (size < 2)
52*c2c66affSColin Finck goto range;
53*c2c66affSColin Finck
54*c2c66affSColin Finck memmove(p, directory, copylen);
55*c2c66affSColin Finck
56*c2c66affSColin Finck if (size <= len)
57*c2c66affSColin Finck goto range;
58*c2c66affSColin Finck
59*c2c66affSColin Finck p += copylen;
60*c2c66affSColin Finck size -= copylen;
61*c2c66affSColin Finck
62*c2c66affSColin Finck if (needs_separator)
63*c2c66affSColin Finck {
64*c2c66affSColin Finck if (size < 2)
65*c2c66affSColin Finck goto range;
66*c2c66affSColin Finck
67*c2c66affSColin Finck *p++ = '\\';
68*c2c66affSColin Finck size -= 1;
69*c2c66affSColin Finck }
70*c2c66affSColin Finck }
71*c2c66affSColin Finck
72*c2c66affSColin Finck if (filename && filename[0])
73*c2c66affSColin Finck {
74*c2c66affSColin Finck size_t len = strlen(filename);
75*c2c66affSColin Finck size_t copylen = min(size - 1, len);
76*c2c66affSColin Finck
77*c2c66affSColin Finck if (size < 2)
78*c2c66affSColin Finck goto range;
79*c2c66affSColin Finck
80*c2c66affSColin Finck memmove(p, filename, copylen);
81*c2c66affSColin Finck
82*c2c66affSColin Finck if (size <= len)
83*c2c66affSColin Finck goto range;
84*c2c66affSColin Finck
85*c2c66affSColin Finck p += len;
86*c2c66affSColin Finck size -= len;
87*c2c66affSColin Finck }
88*c2c66affSColin Finck
89*c2c66affSColin Finck if (extension && extension[0])
90*c2c66affSColin Finck {
91*c2c66affSColin Finck size_t len = strlen(extension);
92*c2c66affSColin Finck unsigned int needs_period = extension[0] != '.';
93*c2c66affSColin Finck size_t copylen;
94*c2c66affSColin Finck
95*c2c66affSColin Finck if (size < 2)
96*c2c66affSColin Finck goto range;
97*c2c66affSColin Finck
98*c2c66affSColin Finck if (needs_period)
99*c2c66affSColin Finck {
100*c2c66affSColin Finck *p++ = '.';
101*c2c66affSColin Finck size -= 1;
102*c2c66affSColin Finck }
103*c2c66affSColin Finck
104*c2c66affSColin Finck copylen = min(size - 1, len);
105*c2c66affSColin Finck memcpy(p, extension, copylen);
106*c2c66affSColin Finck
107*c2c66affSColin Finck if (size <= len)
108*c2c66affSColin Finck goto range;
109*c2c66affSColin Finck
110*c2c66affSColin Finck p += copylen;
111*c2c66affSColin Finck }
112*c2c66affSColin Finck
113*c2c66affSColin Finck *p = '\0';
114*c2c66affSColin Finck return 0;
115*c2c66affSColin Finck
116*c2c66affSColin Finck range:
117*c2c66affSColin Finck path[0] = '\0';
118*c2c66affSColin Finck *_errno() = ERANGE;
119*c2c66affSColin Finck return ERANGE;
120*c2c66affSColin Finck }
121