rugged 0.17.0.b7 → 0.18.0.b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (310) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +88 -32
  3. data/ext/rugged/extconf.rb +4 -2
  4. data/ext/rugged/rugged.c +72 -10
  5. data/ext/rugged/rugged.h +14 -10
  6. data/ext/rugged/rugged_blob.c +8 -10
  7. data/ext/rugged/rugged_branch.c +11 -14
  8. data/ext/rugged/rugged_commit.c +31 -24
  9. data/ext/rugged/rugged_config.c +2 -2
  10. data/ext/rugged/rugged_index.c +133 -198
  11. data/ext/rugged/rugged_note.c +372 -0
  12. data/ext/rugged/rugged_object.c +50 -22
  13. data/ext/rugged/rugged_reference.c +122 -130
  14. data/ext/rugged/rugged_remote.c +72 -29
  15. data/ext/rugged/rugged_repo.c +402 -20
  16. data/ext/rugged/rugged_revwalk.c +7 -3
  17. data/ext/rugged/rugged_settings.c +110 -0
  18. data/ext/rugged/rugged_signature.c +23 -7
  19. data/ext/rugged/rugged_tag.c +32 -16
  20. data/ext/rugged/rugged_tree.c +44 -15
  21. data/lib/rugged.rb +1 -0
  22. data/lib/rugged/index.rb +8 -0
  23. data/lib/rugged/remote.rb +13 -0
  24. data/lib/rugged/repository.rb +3 -3
  25. data/lib/rugged/version.rb +1 -1
  26. data/test/blob_test.rb +13 -15
  27. data/test/branch_test.rb +32 -67
  28. data/test/commit_test.rb +50 -12
  29. data/test/config_test.rb +12 -11
  30. data/test/coverage/HEAD.json +1 -1
  31. data/test/coverage/cover.rb +40 -21
  32. data/test/errors_test.rb +34 -0
  33. data/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 +0 -0
  34. data/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 +0 -0
  35. data/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f +0 -0
  36. data/test/fixtures/testrepo.git/logs/refs/notes/commits +1 -0
  37. data/test/fixtures/testrepo.git/objects/44/1034f860c1d5d90e4188d11ae0d325176869a8 +1 -0
  38. data/test/fixtures/testrepo.git/objects/60/d415052a33de2150bf68757f6461df4f563ae4 +0 -0
  39. data/test/fixtures/testrepo.git/objects/68/8a8f4ef7496901d15322972f96e212a9e466cc +1 -0
  40. data/test/fixtures/testrepo.git/objects/94/eca2de348d5f672faf56b0decafa5937e3235e +0 -0
  41. data/test/fixtures/testrepo.git/objects/9b/7384fe1676186192842f5d3e129457b62db9e3 +0 -0
  42. data/test/fixtures/testrepo.git/objects/b7/4713326bc972cc15751ed504dca6f6f3b91f7a +3 -0
  43. data/test/fixtures/testrepo.git/refs/notes/commits +1 -0
  44. data/test/index_test.rb +65 -69
  45. data/test/lib_test.rb +76 -11
  46. data/test/note_test.rb +158 -0
  47. data/test/object_test.rb +8 -11
  48. data/test/reference_test.rb +77 -85
  49. data/test/remote_test.rb +86 -8
  50. data/test/repo_pack_test.rb +9 -7
  51. data/test/repo_reset_test.rb +80 -0
  52. data/test/repo_test.rb +176 -53
  53. data/test/tag_test.rb +44 -7
  54. data/test/test_helper.rb +63 -35
  55. data/test/tree_test.rb +34 -13
  56. data/test/walker_test.rb +14 -14
  57. data/vendor/libgit2/Makefile.embed +1 -1
  58. data/vendor/libgit2/deps/http-parser/http_parser.c +974 -578
  59. data/vendor/libgit2/deps/http-parser/http_parser.h +106 -70
  60. data/vendor/libgit2/deps/regex/regcomp.c +7 -6
  61. data/vendor/libgit2/deps/regex/regex_internal.c +1 -1
  62. data/vendor/libgit2/deps/regex/regex_internal.h +12 -3
  63. data/vendor/libgit2/deps/regex/regexec.c +5 -5
  64. data/vendor/libgit2/include/git2.h +5 -1
  65. data/vendor/libgit2/include/git2/attr.h +4 -2
  66. data/vendor/libgit2/include/git2/blob.h +39 -12
  67. data/vendor/libgit2/include/git2/branch.h +123 -35
  68. data/vendor/libgit2/include/git2/checkout.h +206 -48
  69. data/vendor/libgit2/include/git2/clone.h +72 -27
  70. data/vendor/libgit2/include/git2/commit.h +20 -17
  71. data/vendor/libgit2/include/git2/common.h +67 -1
  72. data/vendor/libgit2/include/git2/config.h +81 -60
  73. data/vendor/libgit2/include/git2/cred_helpers.h +53 -0
  74. data/vendor/libgit2/include/git2/diff.h +459 -150
  75. data/vendor/libgit2/include/git2/errors.h +9 -1
  76. data/vendor/libgit2/include/git2/graph.h +41 -0
  77. data/vendor/libgit2/include/git2/ignore.h +7 -6
  78. data/vendor/libgit2/include/git2/index.h +323 -97
  79. data/vendor/libgit2/include/git2/indexer.h +27 -59
  80. data/vendor/libgit2/include/git2/inttypes.h +4 -0
  81. data/vendor/libgit2/include/git2/merge.h +13 -3
  82. data/vendor/libgit2/include/git2/message.h +14 -8
  83. data/vendor/libgit2/include/git2/net.h +9 -7
  84. data/vendor/libgit2/include/git2/notes.h +88 -29
  85. data/vendor/libgit2/include/git2/object.h +16 -6
  86. data/vendor/libgit2/include/git2/odb.h +80 -17
  87. data/vendor/libgit2/include/git2/odb_backend.h +47 -11
  88. data/vendor/libgit2/include/git2/oid.h +26 -17
  89. data/vendor/libgit2/include/git2/pack.h +62 -8
  90. data/vendor/libgit2/include/git2/push.h +131 -0
  91. data/vendor/libgit2/include/git2/refdb.h +103 -0
  92. data/vendor/libgit2/include/git2/refdb_backend.h +109 -0
  93. data/vendor/libgit2/include/git2/reflog.h +30 -21
  94. data/vendor/libgit2/include/git2/refs.h +215 -193
  95. data/vendor/libgit2/include/git2/refspec.h +22 -2
  96. data/vendor/libgit2/include/git2/remote.h +158 -37
  97. data/vendor/libgit2/include/git2/repository.h +150 -31
  98. data/vendor/libgit2/include/git2/reset.h +43 -9
  99. data/vendor/libgit2/include/git2/revparse.h +48 -4
  100. data/vendor/libgit2/include/git2/revwalk.h +25 -10
  101. data/vendor/libgit2/include/git2/signature.h +20 -12
  102. data/vendor/libgit2/include/git2/stash.h +121 -0
  103. data/vendor/libgit2/include/git2/status.h +122 -53
  104. data/vendor/libgit2/include/git2/strarray.h +17 -11
  105. data/vendor/libgit2/include/git2/submodule.h +42 -7
  106. data/vendor/libgit2/include/git2/tag.h +72 -59
  107. data/vendor/libgit2/include/git2/threads.h +4 -2
  108. data/vendor/libgit2/include/git2/trace.h +68 -0
  109. data/vendor/libgit2/include/git2/transport.h +328 -0
  110. data/vendor/libgit2/include/git2/tree.h +149 -120
  111. data/vendor/libgit2/include/git2/types.h +13 -12
  112. data/vendor/libgit2/include/git2/version.h +3 -3
  113. data/vendor/libgit2/src/amiga/map.c +2 -2
  114. data/vendor/libgit2/src/attr.c +58 -48
  115. data/vendor/libgit2/src/attr.h +4 -18
  116. data/vendor/libgit2/src/attr_file.c +30 -6
  117. data/vendor/libgit2/src/attr_file.h +6 -8
  118. data/vendor/libgit2/src/attrcache.h +24 -0
  119. data/vendor/libgit2/src/blob.c +30 -7
  120. data/vendor/libgit2/src/blob.h +1 -1
  121. data/vendor/libgit2/src/branch.c +361 -68
  122. data/vendor/libgit2/src/branch.h +17 -0
  123. data/vendor/libgit2/src/bswap.h +1 -1
  124. data/vendor/libgit2/src/buf_text.c +291 -0
  125. data/vendor/libgit2/src/buf_text.h +122 -0
  126. data/vendor/libgit2/src/buffer.c +27 -101
  127. data/vendor/libgit2/src/buffer.h +54 -39
  128. data/vendor/libgit2/src/cache.c +15 -6
  129. data/vendor/libgit2/src/cache.h +1 -1
  130. data/vendor/libgit2/src/cc-compat.h +3 -1
  131. data/vendor/libgit2/src/checkout.c +1165 -222
  132. data/vendor/libgit2/src/checkout.h +24 -0
  133. data/vendor/libgit2/src/clone.c +171 -86
  134. data/vendor/libgit2/src/commit.c +44 -45
  135. data/vendor/libgit2/src/commit.h +3 -3
  136. data/vendor/libgit2/src/commit_list.c +194 -0
  137. data/vendor/libgit2/src/commit_list.h +49 -0
  138. data/vendor/libgit2/src/common.h +44 -10
  139. data/vendor/libgit2/src/compress.c +1 -1
  140. data/vendor/libgit2/src/compress.h +1 -1
  141. data/vendor/libgit2/src/config.c +211 -124
  142. data/vendor/libgit2/src/config.h +23 -4
  143. data/vendor/libgit2/src/config_cache.c +2 -2
  144. data/vendor/libgit2/src/config_file.c +129 -53
  145. data/vendor/libgit2/src/config_file.h +10 -8
  146. data/vendor/libgit2/src/crlf.c +66 -67
  147. data/vendor/libgit2/src/date.c +12 -12
  148. data/vendor/libgit2/src/delta-apply.c +14 -1
  149. data/vendor/libgit2/src/delta-apply.h +18 -1
  150. data/vendor/libgit2/src/delta.c +40 -107
  151. data/vendor/libgit2/src/delta.h +19 -17
  152. data/vendor/libgit2/src/diff.c +347 -496
  153. data/vendor/libgit2/src/diff.h +27 -1
  154. data/vendor/libgit2/src/diff_output.c +564 -249
  155. data/vendor/libgit2/src/diff_output.h +15 -8
  156. data/vendor/libgit2/src/diff_tform.c +687 -0
  157. data/vendor/libgit2/src/errors.c +27 -36
  158. data/vendor/libgit2/src/fetch.c +13 -351
  159. data/vendor/libgit2/src/fetch.h +13 -3
  160. data/vendor/libgit2/src/fetchhead.c +295 -0
  161. data/vendor/libgit2/src/fetchhead.h +34 -0
  162. data/vendor/libgit2/src/filebuf.c +42 -15
  163. data/vendor/libgit2/src/filebuf.h +4 -2
  164. data/vendor/libgit2/src/fileops.c +466 -113
  165. data/vendor/libgit2/src/fileops.h +154 -28
  166. data/vendor/libgit2/src/filter.c +3 -75
  167. data/vendor/libgit2/src/filter.h +1 -29
  168. data/vendor/libgit2/src/fnmatch.c +1 -1
  169. data/vendor/libgit2/src/fnmatch.h +1 -1
  170. data/vendor/libgit2/src/global.c +54 -10
  171. data/vendor/libgit2/src/global.h +10 -1
  172. data/vendor/libgit2/src/graph.c +178 -0
  173. data/vendor/libgit2/src/hash.c +25 -52
  174. data/vendor/libgit2/src/hash.h +21 -9
  175. data/vendor/libgit2/src/{sha1/sha1.c → hash/hash_generic.c} +20 -12
  176. data/vendor/libgit2/src/hash/hash_generic.h +24 -0
  177. data/vendor/libgit2/src/hash/hash_openssl.h +45 -0
  178. data/vendor/libgit2/src/hash/hash_win32.c +291 -0
  179. data/vendor/libgit2/src/hash/hash_win32.h +140 -0
  180. data/vendor/libgit2/src/hashsig.c +368 -0
  181. data/vendor/libgit2/src/hashsig.h +72 -0
  182. data/vendor/libgit2/src/ignore.c +22 -15
  183. data/vendor/libgit2/src/ignore.h +6 -1
  184. data/vendor/libgit2/src/index.c +770 -171
  185. data/vendor/libgit2/src/index.h +13 -5
  186. data/vendor/libgit2/src/indexer.c +286 -431
  187. data/vendor/libgit2/src/iterator.c +854 -466
  188. data/vendor/libgit2/src/iterator.h +134 -109
  189. data/vendor/libgit2/src/map.h +1 -1
  190. data/vendor/libgit2/src/merge.c +296 -0
  191. data/vendor/libgit2/src/merge.h +22 -0
  192. data/vendor/libgit2/src/message.c +1 -1
  193. data/vendor/libgit2/src/message.h +1 -1
  194. data/vendor/libgit2/src/mwindow.c +35 -30
  195. data/vendor/libgit2/src/mwindow.h +2 -2
  196. data/vendor/libgit2/src/netops.c +162 -98
  197. data/vendor/libgit2/src/netops.h +50 -15
  198. data/vendor/libgit2/src/notes.c +109 -58
  199. data/vendor/libgit2/src/notes.h +2 -1
  200. data/vendor/libgit2/src/object.c +46 -57
  201. data/vendor/libgit2/src/object.h +1 -8
  202. data/vendor/libgit2/src/odb.c +151 -40
  203. data/vendor/libgit2/src/odb.h +5 -1
  204. data/vendor/libgit2/src/odb_loose.c +4 -5
  205. data/vendor/libgit2/src/odb_pack.c +122 -80
  206. data/vendor/libgit2/src/offmap.h +65 -0
  207. data/vendor/libgit2/src/oid.c +12 -4
  208. data/vendor/libgit2/src/oidmap.h +1 -1
  209. data/vendor/libgit2/src/pack-objects.c +88 -61
  210. data/vendor/libgit2/src/pack-objects.h +8 -8
  211. data/vendor/libgit2/src/pack.c +293 -28
  212. data/vendor/libgit2/src/pack.h +49 -4
  213. data/vendor/libgit2/src/path.c +103 -14
  214. data/vendor/libgit2/src/path.h +23 -7
  215. data/vendor/libgit2/src/pathspec.c +168 -0
  216. data/vendor/libgit2/src/pathspec.h +40 -0
  217. data/vendor/libgit2/src/pool.c +29 -4
  218. data/vendor/libgit2/src/pool.h +8 -1
  219. data/vendor/libgit2/src/posix.c +26 -27
  220. data/vendor/libgit2/src/posix.h +2 -3
  221. data/vendor/libgit2/src/pqueue.c +23 -1
  222. data/vendor/libgit2/src/pqueue.h +23 -1
  223. data/vendor/libgit2/src/push.c +653 -0
  224. data/vendor/libgit2/src/push.h +51 -0
  225. data/vendor/libgit2/src/refdb.c +185 -0
  226. data/vendor/libgit2/src/refdb.h +46 -0
  227. data/vendor/libgit2/src/refdb_fs.c +1024 -0
  228. data/vendor/libgit2/src/refdb_fs.h +15 -0
  229. data/vendor/libgit2/src/reflog.c +77 -45
  230. data/vendor/libgit2/src/reflog.h +1 -3
  231. data/vendor/libgit2/src/refs.c +366 -1326
  232. data/vendor/libgit2/src/refs.h +22 -13
  233. data/vendor/libgit2/src/refspec.c +46 -7
  234. data/vendor/libgit2/src/refspec.h +11 -1
  235. data/vendor/libgit2/src/remote.c +758 -120
  236. data/vendor/libgit2/src/remote.h +10 -5
  237. data/vendor/libgit2/src/repo_template.h +6 -6
  238. data/vendor/libgit2/src/repository.c +315 -96
  239. data/vendor/libgit2/src/repository.h +5 -3
  240. data/vendor/libgit2/src/reset.c +99 -81
  241. data/vendor/libgit2/src/revparse.c +157 -84
  242. data/vendor/libgit2/src/revwalk.c +68 -470
  243. data/vendor/libgit2/src/revwalk.h +44 -0
  244. data/vendor/libgit2/src/sha1_lookup.c +1 -1
  245. data/vendor/libgit2/src/sha1_lookup.h +1 -1
  246. data/vendor/libgit2/src/signature.c +68 -200
  247. data/vendor/libgit2/src/signature.h +1 -1
  248. data/vendor/libgit2/src/stash.c +663 -0
  249. data/vendor/libgit2/src/status.c +101 -79
  250. data/vendor/libgit2/src/strmap.h +1 -1
  251. data/vendor/libgit2/src/submodule.c +67 -51
  252. data/vendor/libgit2/src/submodule.h +1 -1
  253. data/vendor/libgit2/src/tag.c +35 -29
  254. data/vendor/libgit2/src/tag.h +1 -1
  255. data/vendor/libgit2/src/thread-utils.c +1 -1
  256. data/vendor/libgit2/src/thread-utils.h +2 -2
  257. data/vendor/libgit2/src/trace.c +39 -0
  258. data/vendor/libgit2/src/trace.h +56 -0
  259. data/vendor/libgit2/src/transport.c +81 -34
  260. data/vendor/libgit2/src/transports/cred.c +60 -0
  261. data/vendor/libgit2/src/transports/cred_helpers.c +49 -0
  262. data/vendor/libgit2/src/transports/git.c +234 -127
  263. data/vendor/libgit2/src/transports/http.c +761 -433
  264. data/vendor/libgit2/src/transports/local.c +460 -64
  265. data/vendor/libgit2/src/transports/smart.c +345 -0
  266. data/vendor/libgit2/src/transports/smart.h +179 -0
  267. data/vendor/libgit2/src/{pkt.c → transports/smart_pkt.c} +131 -12
  268. data/vendor/libgit2/src/transports/smart_protocol.c +856 -0
  269. data/vendor/libgit2/src/transports/winhttp.c +1136 -0
  270. data/vendor/libgit2/src/tree-cache.c +2 -2
  271. data/vendor/libgit2/src/tree-cache.h +1 -1
  272. data/vendor/libgit2/src/tree.c +239 -166
  273. data/vendor/libgit2/src/tree.h +11 -2
  274. data/vendor/libgit2/src/tsort.c +39 -23
  275. data/vendor/libgit2/src/unix/map.c +1 -1
  276. data/vendor/libgit2/src/unix/posix.h +12 -2
  277. data/vendor/libgit2/src/unix/realpath.c +30 -0
  278. data/vendor/libgit2/src/util.c +250 -13
  279. data/vendor/libgit2/src/util.h +71 -14
  280. data/vendor/libgit2/src/vector.c +123 -60
  281. data/vendor/libgit2/src/vector.h +24 -22
  282. data/vendor/libgit2/src/win32/dir.c +1 -1
  283. data/vendor/libgit2/src/win32/dir.h +1 -1
  284. data/vendor/libgit2/src/win32/error.c +77 -0
  285. data/vendor/libgit2/src/win32/error.h +13 -0
  286. data/vendor/libgit2/src/win32/findfile.c +143 -54
  287. data/vendor/libgit2/src/win32/findfile.h +10 -6
  288. data/vendor/libgit2/src/win32/map.c +1 -1
  289. data/vendor/libgit2/src/win32/mingw-compat.h +1 -1
  290. data/vendor/libgit2/src/win32/msvc-compat.h +10 -1
  291. data/vendor/libgit2/src/win32/posix.h +10 -1
  292. data/vendor/libgit2/src/win32/posix_w32.c +132 -63
  293. data/vendor/libgit2/src/win32/precompiled.c +1 -1
  294. data/vendor/libgit2/src/win32/pthread.c +1 -1
  295. data/vendor/libgit2/src/win32/pthread.h +1 -1
  296. data/vendor/libgit2/src/win32/utf-conv.c +5 -5
  297. data/vendor/libgit2/src/win32/utf-conv.h +3 -3
  298. data/vendor/libgit2/src/win32/version.h +20 -0
  299. metadata +308 -252
  300. data/test/fixtures/testrepo.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
  301. data/test/fixtures/testrepo.git/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 +0 -0
  302. data/test/fixtures/testrepo.git/objects/a3/e05719b428a2d0ed7a55c4ce53dcc5768c6d5e +0 -0
  303. data/test/index_test.rb~ +0 -218
  304. data/vendor/libgit2/src/pkt.h +0 -91
  305. data/vendor/libgit2/src/ppc/sha1.c +0 -70
  306. data/vendor/libgit2/src/ppc/sha1.h +0 -26
  307. data/vendor/libgit2/src/protocol.c +0 -110
  308. data/vendor/libgit2/src/protocol.h +0 -21
  309. data/vendor/libgit2/src/sha1.h +0 -33
  310. data/vendor/libgit2/src/transport.h +0 -148
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+ #ifndef INCLUDE_merge_h__
8
+ #define INCLUDE_merge_h__
9
+
10
+ #include "git2/types.h"
11
+ #include "git2/merge.h"
12
+ #include "commit_list.h"
13
+ #include "vector.h"
14
+
15
+ #define GIT_MERGE_MSG_FILE "MERGE_MSG"
16
+ #define GIT_MERGE_MODE_FILE "MERGE_MODE"
17
+
18
+ #define MERGE_CONFIG_FILE_MODE 0666
19
+
20
+ int git_merge__bases_many(git_commit_list **out, git_revwalk *walk, git_commit_list_node *one, git_vector *twos);
21
+
22
+ #endif
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -20,17 +20,8 @@
20
20
  #define DEFAULT_MAPPED_LIMIT \
21
21
  ((1024 * 1024) * (sizeof(void*) >= 8 ? 8192ULL : 256UL))
22
22
 
23
- /*
24
- * These are the global options for mmmap limits.
25
- * TODO: allow the user to change these
26
- */
27
- static struct {
28
- size_t window_size;
29
- size_t mapped_limit;
30
- } _mw_options = {
31
- DEFAULT_WINDOW_SIZE,
32
- DEFAULT_MAPPED_LIMIT,
33
- };
23
+ size_t git_mwindow__window_size = DEFAULT_WINDOW_SIZE;
24
+ size_t git_mwindow__mapped_limit = DEFAULT_MAPPED_LIMIT;
34
25
 
35
26
  /* Whenever you want to read or modify this, grab git__mwindow_mutex */
36
27
  static git_mwindow_ctl mem_ctl;
@@ -42,9 +33,12 @@ static git_mwindow_ctl mem_ctl;
42
33
  void git_mwindow_free_all(git_mwindow_file *mwf)
43
34
  {
44
35
  git_mwindow_ctl *ctl = &mem_ctl;
45
- unsigned int i;
36
+ size_t i;
46
37
 
47
- git_mutex_lock(&git__mwindow_mutex);
38
+ if (git_mutex_lock(&git__mwindow_mutex)) {
39
+ giterr_set(GITERR_THREAD, "unable to lock mwindow mutex");
40
+ return;
41
+ }
48
42
 
49
43
  /*
50
44
  * Remove these windows from the global list
@@ -121,7 +115,7 @@ static void git_mwindow_scan_lru(
121
115
  static int git_mwindow_close_lru(git_mwindow_file *mwf)
122
116
  {
123
117
  git_mwindow_ctl *ctl = &mem_ctl;
124
- unsigned int i;
118
+ size_t i;
125
119
  git_mwindow *lru_w = NULL, *lru_l = NULL, **list = &mwf->windows;
126
120
 
127
121
  /* FIXME: Does this give us any advantage? */
@@ -163,7 +157,7 @@ static git_mwindow *new_window(
163
157
  git_off_t offset)
164
158
  {
165
159
  git_mwindow_ctl *ctl = &mem_ctl;
166
- size_t walign = _mw_options.window_size / 2;
160
+ size_t walign = git_mwindow__window_size / 2;
167
161
  git_off_t len;
168
162
  git_mwindow *w;
169
163
 
@@ -176,16 +170,16 @@ static git_mwindow *new_window(
176
170
  w->offset = (offset / walign) * walign;
177
171
 
178
172
  len = size - w->offset;
179
- if (len > (git_off_t)_mw_options.window_size)
180
- len = (git_off_t)_mw_options.window_size;
173
+ if (len > (git_off_t)git_mwindow__window_size)
174
+ len = (git_off_t)git_mwindow__window_size;
181
175
 
182
176
  ctl->mapped += (size_t)len;
183
177
 
184
- while (_mw_options.mapped_limit < ctl->mapped &&
178
+ while (git_mwindow__mapped_limit < ctl->mapped &&
185
179
  git_mwindow_close_lru(mwf) == 0) /* nop */;
186
180
 
187
181
  /*
188
- * We treat _mw_options.mapped_limit as a soft limit. If we can't find a
182
+ * We treat `mapped_limit` as a soft limit. If we can't find a
189
183
  * window to close and are above the limit, we still mmap the new
190
184
  * window.
191
185
  */
@@ -221,7 +215,11 @@ unsigned char *git_mwindow_open(
221
215
  git_mwindow_ctl *ctl = &mem_ctl;
222
216
  git_mwindow *w = *cursor;
223
217
 
224
- git_mutex_lock(&git__mwindow_mutex);
218
+ if (git_mutex_lock(&git__mwindow_mutex)) {
219
+ giterr_set(GITERR_THREAD, "unable to lock mwindow mutex");
220
+ return NULL;
221
+ }
222
+
225
223
  if (!w || !(git_mwindow_contains(w, offset) && git_mwindow_contains(w, offset + extra))) {
226
224
  if (w) {
227
225
  w->inuse_cnt--;
@@ -269,7 +267,11 @@ int git_mwindow_file_register(git_mwindow_file *mwf)
269
267
  git_mwindow_ctl *ctl = &mem_ctl;
270
268
  int ret;
271
269
 
272
- git_mutex_lock(&git__mwindow_mutex);
270
+ if (git_mutex_lock(&git__mwindow_mutex)) {
271
+ giterr_set(GITERR_THREAD, "unable to lock mwindow mutex");
272
+ return -1;
273
+ }
274
+
273
275
  if (ctl->windowfiles.length == 0 &&
274
276
  git_vector_init(&ctl->windowfiles, 8, NULL) < 0) {
275
277
  git_mutex_unlock(&git__mwindow_mutex);
@@ -282,31 +284,34 @@ int git_mwindow_file_register(git_mwindow_file *mwf)
282
284
  return ret;
283
285
  }
284
286
 
285
- int git_mwindow_file_deregister(git_mwindow_file *mwf)
287
+ void git_mwindow_file_deregister(git_mwindow_file *mwf)
286
288
  {
287
289
  git_mwindow_ctl *ctl = &mem_ctl;
288
290
  git_mwindow_file *cur;
289
- unsigned int i;
291
+ size_t i;
292
+
293
+ if (git_mutex_lock(&git__mwindow_mutex))
294
+ return;
290
295
 
291
- git_mutex_lock(&git__mwindow_mutex);
292
296
  git_vector_foreach(&ctl->windowfiles, i, cur) {
293
297
  if (cur == mwf) {
294
298
  git_vector_remove(&ctl->windowfiles, i);
295
299
  git_mutex_unlock(&git__mwindow_mutex);
296
- return 0;
300
+ return;
297
301
  }
298
302
  }
299
303
  git_mutex_unlock(&git__mwindow_mutex);
300
-
301
- giterr_set(GITERR_ODB, "Failed to find the memory window file to deregister");
302
- return -1;
303
304
  }
304
305
 
305
306
  void git_mwindow_close(git_mwindow **window)
306
307
  {
307
308
  git_mwindow *w = *window;
308
309
  if (w) {
309
- git_mutex_lock(&git__mwindow_mutex);
310
+ if (git_mutex_lock(&git__mwindow_mutex)) {
311
+ giterr_set(GITERR_THREAD, "unable to lock mwindow mutex");
312
+ return;
313
+ }
314
+
310
315
  w->inuse_cnt--;
311
316
  git_mutex_unlock(&git__mwindow_mutex);
312
317
  *window = NULL;
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -39,7 +39,7 @@ int git_mwindow_contains(git_mwindow *win, git_off_t offset);
39
39
  void git_mwindow_free_all(git_mwindow_file *mwf);
40
40
  unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, git_off_t offset, size_t extra, unsigned int *left);
41
41
  int git_mwindow_file_register(git_mwindow_file *mwf);
42
- int git_mwindow_file_deregister(git_mwindow_file *mwf);
42
+ void git_mwindow_file_deregister(git_mwindow_file *mwf);
43
43
  void git_mwindow_close(git_mwindow **w_cursor);
44
44
 
45
45
  #endif
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -10,16 +10,22 @@
10
10
  # include <sys/select.h>
11
11
  # include <sys/time.h>
12
12
  # include <netdb.h>
13
+ # include <netinet/in.h>
13
14
  # include <arpa/inet.h>
14
15
  #else
15
16
  # include <ws2tcpip.h>
16
17
  # ifdef _MSC_VER
17
- # pragma comment(lib, "ws2_32.lib")
18
+ # pragma comment(lib, "ws2_32")
18
19
  # endif
19
20
  #endif
20
21
 
22
+ #ifdef __FreeBSD__
23
+ # include <netinet/in.h>
24
+ #endif
25
+
21
26
  #ifdef GIT_SSL
22
27
  # include <openssl/ssl.h>
28
+ # include <openssl/err.h>
23
29
  # include <openssl/x509v3.h>
24
30
  #endif
25
31
 
@@ -30,19 +36,19 @@
30
36
  #include "netops.h"
31
37
  #include "posix.h"
32
38
  #include "buffer.h"
33
- #include "transport.h"
34
39
 
35
40
  #ifdef GIT_WIN32
36
41
  static void net_set_error(const char *str)
37
42
  {
38
- int size, error = WSAGetLastError();
39
- LPSTR err_str = NULL;
40
-
41
- size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
42
- 0, error, 0, (LPSTR)&err_str, 0, 0);
43
+ int error = WSAGetLastError();
44
+ char * win32_error = git_win32_get_error_message(error);
43
45
 
44
- giterr_set(GITERR_NET, "%s: %s", str, err_str);
45
- LocalFree(err_str);
46
+ if (win32_error) {
47
+ giterr_set(GITERR_NET, "%s: %s", str, win32_error);
48
+ git__free(win32_error);
49
+ } else {
50
+ giterr_set(GITERR_NET, str);
51
+ }
46
52
  }
47
53
  #else
48
54
  static void net_set_error(const char *str)
@@ -108,8 +114,8 @@ static int gitno__recv_ssl(gitno_buffer *buf)
108
114
  int ret;
109
115
 
110
116
  do {
111
- ret = SSL_read(buf->ssl->ssl, buf->data + buf->offset, buf->len - buf->offset);
112
- } while (SSL_get_error(buf->ssl->ssl, ret) == SSL_ERROR_WANT_READ);
117
+ ret = SSL_read(buf->socket->ssl.ssl, buf->data + buf->offset, buf->len - buf->offset);
118
+ } while (SSL_get_error(buf->socket->ssl.ssl, ret) == SSL_ERROR_WANT_READ);
113
119
 
114
120
  if (ret < 0) {
115
121
  net_set_error("Error receiving socket data");
@@ -121,11 +127,11 @@ static int gitno__recv_ssl(gitno_buffer *buf)
121
127
  }
122
128
  #endif
123
129
 
124
- int gitno__recv(gitno_buffer *buf)
130
+ static int gitno__recv(gitno_buffer *buf)
125
131
  {
126
132
  int ret;
127
133
 
128
- ret = p_recv(buf->fd, buf->data + buf->offset, buf->len - buf->offset, 0);
134
+ ret = p_recv(buf->socket->socket, buf->data + buf->offset, buf->len - buf->offset, 0);
129
135
  if (ret < 0) {
130
136
  net_set_error("Error receiving socket data");
131
137
  return -1;
@@ -136,31 +142,31 @@ int gitno__recv(gitno_buffer *buf)
136
142
  }
137
143
 
138
144
  void gitno_buffer_setup_callback(
139
- git_transport *t,
145
+ gitno_socket *socket,
140
146
  gitno_buffer *buf,
141
147
  char *data,
142
148
  size_t len,
143
149
  int (*recv)(gitno_buffer *buf), void *cb_data)
144
150
  {
145
- memset(buf, 0x0, sizeof(gitno_buffer));
146
151
  memset(data, 0x0, len);
147
152
  buf->data = data;
148
153
  buf->len = len;
149
154
  buf->offset = 0;
150
- buf->fd = t->socket;
155
+ buf->socket = socket;
151
156
  buf->recv = recv;
152
157
  buf->cb_data = cb_data;
153
158
  }
154
159
 
155
- void gitno_buffer_setup(git_transport *t, gitno_buffer *buf, char *data, size_t len)
160
+ void gitno_buffer_setup(gitno_socket *socket, gitno_buffer *buf, char *data, size_t len)
156
161
  {
157
162
  #ifdef GIT_SSL
158
- if (t->use_ssl) {
159
- gitno_buffer_setup_callback(t, buf, data, len, gitno__recv_ssl, NULL);
160
- buf->ssl = &t->ssl;
161
- } else
163
+ if (socket->ssl.ctx) {
164
+ gitno_buffer_setup_callback(socket, buf, data, len, gitno__recv_ssl, NULL);
165
+ return;
166
+ }
162
167
  #endif
163
- gitno_buffer_setup_callback(t, buf, data, len, gitno__recv, NULL);
168
+
169
+ gitno_buffer_setup_callback(socket, buf, data, len, gitno__recv, NULL);
164
170
  }
165
171
 
166
172
  /* Consume up to ptr and move the rest of the buffer to the beginning */
@@ -186,31 +192,23 @@ void gitno_consume_n(gitno_buffer *buf, size_t cons)
186
192
  buf->offset -= cons;
187
193
  }
188
194
 
189
- int gitno_ssl_teardown(git_transport *t)
190
- {
191
195
  #ifdef GIT_SSL
192
- int ret;
193
- #endif
194
196
 
195
- if (!t->use_ssl)
196
- return 0;
197
-
198
- #ifdef GIT_SSL
197
+ static int gitno_ssl_teardown(gitno_ssl *ssl)
198
+ {
199
+ int ret;
199
200
 
200
- do {
201
- ret = SSL_shutdown(t->ssl.ssl);
202
- } while (ret == 0);
201
+ ret = SSL_shutdown(ssl->ssl);
203
202
  if (ret < 0)
204
- return ssl_set_error(&t->ssl, ret);
203
+ ret = ssl_set_error(ssl, ret);
204
+ else
205
+ ret = 0;
205
206
 
206
- SSL_free(t->ssl.ssl);
207
- SSL_CTX_free(t->ssl.ctx);
208
- #endif
209
- return 0;
207
+ SSL_free(ssl->ssl);
208
+ SSL_CTX_free(ssl->ctx);
209
+ return ret;
210
210
  }
211
211
 
212
-
213
- #ifdef GIT_SSL
214
212
  /* Match host names according to RFC 2818 rules */
215
213
  static int match_host(const char *pattern, const char *host)
216
214
  {
@@ -261,7 +259,7 @@ static int check_host_name(const char *name, const char *host)
261
259
  return 0;
262
260
  }
263
261
 
264
- static int verify_server_cert(git_transport *t, const char *host)
262
+ static int verify_server_cert(gitno_ssl *ssl, const char *host)
265
263
  {
266
264
  X509 *cert;
267
265
  X509_NAME *peer_name;
@@ -274,24 +272,24 @@ static int verify_server_cert(git_transport *t, const char *host)
274
272
  void *addr;
275
273
  int i = -1,j;
276
274
 
277
- if (SSL_get_verify_result(t->ssl.ssl) != X509_V_OK) {
275
+ if (SSL_get_verify_result(ssl->ssl) != X509_V_OK) {
278
276
  giterr_set(GITERR_SSL, "The SSL certificate is invalid");
279
277
  return -1;
280
278
  }
281
279
 
282
280
  /* Try to parse the host as an IP address to see if it is */
283
- if (inet_pton(AF_INET, host, &addr4)) {
281
+ if (p_inet_pton(AF_INET, host, &addr4)) {
284
282
  type = GEN_IPADD;
285
283
  addr = &addr4;
286
284
  } else {
287
- if(inet_pton(AF_INET6, host, &addr6)) {
285
+ if(p_inet_pton(AF_INET6, host, &addr6)) {
288
286
  type = GEN_IPADD;
289
287
  addr = &addr6;
290
288
  }
291
289
  }
292
290
 
293
291
 
294
- cert = SSL_get_peer_certificate(t->ssl.ssl);
292
+ cert = SSL_get_peer_certificate(ssl->ssl);
295
293
 
296
294
  /* Check the alternative names */
297
295
  alts = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
@@ -375,7 +373,7 @@ static int verify_server_cert(git_transport *t, const char *host)
375
373
 
376
374
  on_error:
377
375
  OPENSSL_free(peer_cn);
378
- return ssl_set_error(&t->ssl, 0);
376
+ return ssl_set_error(ssl, 0);
379
377
 
380
378
  cert_fail:
381
379
  OPENSSL_free(peer_cn);
@@ -383,51 +381,81 @@ cert_fail:
383
381
  return -1;
384
382
  }
385
383
 
386
- static int ssl_setup(git_transport *t, const char *host)
384
+ static int ssl_setup(gitno_socket *socket, const char *host, int flags)
387
385
  {
388
386
  int ret;
389
387
 
390
388
  SSL_library_init();
391
389
  SSL_load_error_strings();
392
- t->ssl.ctx = SSL_CTX_new(SSLv23_method());
393
- if (t->ssl.ctx == NULL)
394
- return ssl_set_error(&t->ssl, 0);
390
+ socket->ssl.ctx = SSL_CTX_new(SSLv23_method());
391
+ if (socket->ssl.ctx == NULL)
392
+ return ssl_set_error(&socket->ssl, 0);
395
393
 
396
- SSL_CTX_set_mode(t->ssl.ctx, SSL_MODE_AUTO_RETRY);
397
- SSL_CTX_set_verify(t->ssl.ctx, SSL_VERIFY_NONE, NULL);
398
- if (!SSL_CTX_set_default_verify_paths(t->ssl.ctx))
399
- return ssl_set_error(&t->ssl, 0);
394
+ SSL_CTX_set_mode(socket->ssl.ctx, SSL_MODE_AUTO_RETRY);
395
+ SSL_CTX_set_verify(socket->ssl.ctx, SSL_VERIFY_NONE, NULL);
396
+ if (!SSL_CTX_set_default_verify_paths(socket->ssl.ctx))
397
+ return ssl_set_error(&socket->ssl, 0);
400
398
 
401
- t->ssl.ssl = SSL_new(t->ssl.ctx);
402
- if (t->ssl.ssl == NULL)
403
- return ssl_set_error(&t->ssl, 0);
399
+ socket->ssl.ssl = SSL_new(socket->ssl.ctx);
400
+ if (socket->ssl.ssl == NULL)
401
+ return ssl_set_error(&socket->ssl, 0);
404
402
 
405
- if((ret = SSL_set_fd(t->ssl.ssl, t->socket)) == 0)
406
- return ssl_set_error(&t->ssl, ret);
403
+ if((ret = SSL_set_fd(socket->ssl.ssl, socket->socket)) == 0)
404
+ return ssl_set_error(&socket->ssl, ret);
407
405
 
408
- if ((ret = SSL_connect(t->ssl.ssl)) <= 0)
409
- return ssl_set_error(&t->ssl, ret);
406
+ if ((ret = SSL_connect(socket->ssl.ssl)) <= 0)
407
+ return ssl_set_error(&socket->ssl, ret);
410
408
 
411
- if (t->check_cert && verify_server_cert(t, host) < 0)
412
- return -1;
409
+ if (GITNO_CONNECT_SSL_NO_CHECK_CERT & flags)
410
+ return 0;
413
411
 
414
- return 0;
412
+ return verify_server_cert(&socket->ssl, host);
415
413
  }
416
- #else
417
- static int ssl_setup(git_transport *t, const char *host)
414
+ #endif
415
+
416
+ static int gitno__close(GIT_SOCKET s)
418
417
  {
419
- GIT_UNUSED(t);
420
- GIT_UNUSED(host);
418
+ #ifdef GIT_WIN32
419
+ if (SOCKET_ERROR == closesocket(s))
420
+ return -1;
421
+
422
+ if (0 != WSACleanup()) {
423
+ giterr_set(GITERR_OS, "Winsock cleanup failed");
424
+ return -1;
425
+ }
426
+
421
427
  return 0;
422
- }
428
+ #else
429
+ return close(s);
423
430
  #endif
431
+ }
424
432
 
425
- int gitno_connect(git_transport *t, const char *host, const char *port)
433
+ int gitno_connect(gitno_socket *s_out, const char *host, const char *port, int flags)
426
434
  {
427
435
  struct addrinfo *info = NULL, *p;
428
436
  struct addrinfo hints;
429
- int ret;
430
437
  GIT_SOCKET s = INVALID_SOCKET;
438
+ int ret;
439
+
440
+ #ifdef GIT_WIN32
441
+ /* on win32, the WSA context needs to be initialized
442
+ * before any socket calls can be performed */
443
+ WSADATA wsd;
444
+
445
+ if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
446
+ giterr_set(GITERR_OS, "Winsock init failed");
447
+ return -1;
448
+ }
449
+
450
+ if (LOBYTE(wsd.wVersion) != 2 || HIBYTE(wsd.wVersion) != 2) {
451
+ WSACleanup();
452
+ giterr_set(GITERR_OS, "Winsock init failed");
453
+ return -1;
454
+ }
455
+ #endif
456
+
457
+ /* Zero the socket structure provided */
458
+ memset(s_out, 0x0, sizeof(gitno_socket));
431
459
 
432
460
  memset(&hints, 0x0, sizeof(struct addrinfo));
433
461
  hints.ai_socktype = SOCK_STREAM;
@@ -451,56 +479,67 @@ int gitno_connect(git_transport *t, const char *host, const char *port)
451
479
  break;
452
480
 
453
481
  /* If we can't connect, try the next one */
454
- gitno_close(s);
482
+ gitno__close(s);
455
483
  s = INVALID_SOCKET;
456
484
  }
457
485
 
458
486
  /* Oops, we couldn't connect to any address */
459
487
  if (s == INVALID_SOCKET && p == NULL) {
460
488
  giterr_set(GITERR_OS, "Failed to connect to %s", host);
489
+ p_freeaddrinfo(info);
461
490
  return -1;
462
491
  }
463
492
 
464
- t->socket = s;
493
+ s_out->socket = s;
465
494
  p_freeaddrinfo(info);
466
495
 
467
- if (t->use_ssl && ssl_setup(t, host) < 0)
496
+ #ifdef GIT_SSL
497
+ if ((flags & GITNO_CONNECT_SSL) && ssl_setup(s_out, host, flags) < 0)
468
498
  return -1;
499
+ #else
500
+ /* SSL is not supported */
501
+ if (flags & GITNO_CONNECT_SSL) {
502
+ giterr_set(GITERR_OS, "SSL is not supported by this copy of libgit2.");
503
+ return -1;
504
+ }
505
+ #endif
469
506
 
470
507
  return 0;
471
508
  }
472
509
 
473
510
  #ifdef GIT_SSL
474
- static int send_ssl(gitno_ssl *ssl, const char *msg, size_t len)
511
+ static int gitno_send_ssl(gitno_ssl *ssl, const char *msg, size_t len, int flags)
475
512
  {
476
513
  int ret;
477
514
  size_t off = 0;
478
515
 
516
+ GIT_UNUSED(flags);
517
+
479
518
  while (off < len) {
480
519
  ret = SSL_write(ssl->ssl, msg + off, len - off);
481
520
  if (ret <= 0 && ret != SSL_ERROR_WANT_WRITE)
482
521
  return ssl_set_error(ssl, ret);
483
522
 
484
523
  off += ret;
485
- }
524
+ }
486
525
 
487
526
  return off;
488
527
  }
489
528
  #endif
490
529
 
491
- int gitno_send(git_transport *t, const char *msg, size_t len, int flags)
530
+ int gitno_send(gitno_socket *socket, const char *msg, size_t len, int flags)
492
531
  {
493
532
  int ret;
494
533
  size_t off = 0;
495
534
 
496
535
  #ifdef GIT_SSL
497
- if (t->use_ssl)
498
- return send_ssl(&t->ssl, msg, len);
536
+ if (socket->ssl.ctx)
537
+ return gitno_send_ssl(&socket->ssl, msg, len, flags);
499
538
  #endif
500
539
 
501
540
  while (off < len) {
502
541
  errno = 0;
503
- ret = p_send(t->socket, msg + off, len - off, flags);
542
+ ret = p_send(socket->socket, msg + off, len - off, flags);
504
543
  if (ret < 0) {
505
544
  net_set_error("Error sending data");
506
545
  return -1;
@@ -512,19 +551,17 @@ int gitno_send(git_transport *t, const char *msg, size_t len, int flags)
512
551
  return (int)off;
513
552
  }
514
553
 
515
-
516
- #ifdef GIT_WIN32
517
- int gitno_close(GIT_SOCKET s)
554
+ int gitno_close(gitno_socket *s)
518
555
  {
519
- return closesocket(s) == SOCKET_ERROR ? -1 : 0;
520
- }
521
- #else
522
- int gitno_close(GIT_SOCKET s)
523
- {
524
- return close(s);
525
- }
556
+ #ifdef GIT_SSL
557
+ if (s->ssl.ctx &&
558
+ gitno_ssl_teardown(&s->ssl) < 0)
559
+ return -1;
526
560
  #endif
527
561
 
562
+ return gitno__close(s->socket);
563
+ }
564
+
528
565
  int gitno_select_in(gitno_buffer *buf, long int sec, long int usec)
529
566
  {
530
567
  fd_set fds;
@@ -534,33 +571,60 @@ int gitno_select_in(gitno_buffer *buf, long int sec, long int usec)
534
571
  tv.tv_usec = usec;
535
572
 
536
573
  FD_ZERO(&fds);
537
- FD_SET(buf->fd, &fds);
574
+ FD_SET(buf->socket->socket, &fds);
538
575
 
539
576
  /* The select(2) interface is silly */
540
- return select((int)buf->fd + 1, &fds, NULL, NULL, &tv);
577
+ return select((int)buf->socket->socket + 1, &fds, NULL, NULL, &tv);
541
578
  }
542
579
 
543
- int gitno_extract_host_and_port(char **host, char **port, const char *url, const char *default_port)
580
+ int gitno_extract_url_parts(
581
+ char **host,
582
+ char **port,
583
+ char **username,
584
+ char **password,
585
+ const char *url,
586
+ const char *default_port)
544
587
  {
545
- char *colon, *slash, *delim;
588
+ char *colon, *slash, *at, *end;
589
+ const char *start;
590
+
591
+ /*
592
+ *
593
+ * ==> [user[:pass]@]hostname.tld[:port]/resource
594
+ */
546
595
 
547
596
  colon = strchr(url, ':');
548
597
  slash = strchr(url, '/');
598
+ at = strchr(url, '@');
549
599
 
550
600
  if (slash == NULL) {
551
601
  giterr_set(GITERR_NET, "Malformed URL: missing /");
552
602
  return -1;
553
603
  }
554
604
 
605
+ start = url;
606
+ if (at && at < slash) {
607
+ start = at+1;
608
+ *username = git__substrdup(url, at - url);
609
+ }
610
+
611
+ if (colon && colon < at) {
612
+ git__free(*username);
613
+ *username = git__substrdup(url, colon-url);
614
+ *password = git__substrdup(colon+1, at-colon-1);
615
+ colon = strchr(at, ':');
616
+ }
617
+
555
618
  if (colon == NULL) {
556
619
  *port = git__strdup(default_port);
557
620
  } else {
558
- *port = git__strndup(colon + 1, slash - colon - 1);
621
+ *port = git__substrdup(colon + 1, slash - colon - 1);
559
622
  }
560
623
  GITERR_CHECK_ALLOC(*port);
561
624
 
562
- delim = colon == NULL ? slash : colon;
563
- *host = git__strndup(url, delim - url);
625
+ end = colon == NULL ? slash : colon;
626
+
627
+ *host = git__substrdup(start, end - start);
564
628
  GITERR_CHECK_ALLOC(*host);
565
629
 
566
630
  return 0;