rugged 0.17.0.b7 → 0.18.0.b1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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;