* Shuffles all data between the two file-descriptors until one of them fails or reaches EOF. * */
| 79 | * Shuffles all data between the two file-descriptors until one of them fails or reaches EOF. |
| 80 | * */ |
| 81 | void shuffleBetweenStreams(int side1, int side2, bool fixSide1AuthToken) |
| 82 | { |
| 83 | char buffer[1000]; |
| 84 | char buffer2[1000]; |
| 85 | |
| 86 | // Set non-blocking mode |
| 87 | int opts = fcntl(side1, F_GETFL); |
| 88 | opts |= O_NONBLOCK; |
| 89 | fcntl(side1, F_SETFL, opts); |
| 90 | |
| 91 | opts = fcntl(side2, F_GETFL); |
| 92 | opts |= O_NONBLOCK; |
| 93 | fcntl(side2, F_SETFL, opts); |
| 94 | |
| 95 | while (true) { |
| 96 | int r1 = read(side1, buffer, 500); // We read less than 1000, so we have same additional space when changing the auth token |
| 97 | int r2 = read(side2, buffer2, 500); |
| 98 | |
| 99 | if (r1 < -1 || r1 == 0) { |
| 100 | if (debug) |
| 101 | std::cerr << "stream 1 failed: " << r1 << std::endl; |
| 102 | return; |
| 103 | } |
| 104 | if (r2 < -1 || r2 == 0) { |
| 105 | if (debug) |
| 106 | std::cerr << "stream 2 failed: " << r2 << std::endl; |
| 107 | return; |
| 108 | } |
| 109 | |
| 110 | if (r1 > 0) { |
| 111 | if (debug) |
| 112 | std::cerr << "transferring " << r1 << " from 1 to 2" << std::endl; |
| 113 | |
| 114 | if (fixSide1AuthToken) { |
| 115 | if (r1 > 15 && memcmp(buffer, "\0AUTH EXTERNAL ", 15) == 0) { |
| 116 | int endPos = -1; |
| 117 | for (int i = 15; i < r1; ++i) { |
| 118 | if (buffer[i] == '\r') { |
| 119 | endPos = i; |
| 120 | break; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | if (endPos != -1) { |
| 125 | std::string oldToken = std::string(buffer + 15, endPos - 15); |
| 126 | std::string newToken = getAuthToken(); |
| 127 | |
| 128 | int difference = newToken.size() - oldToken.size(); |
| 129 | r1 += difference; |
| 130 | assert(r1 > 0 && r1 <= 1000); |
| 131 | memmove(buffer + endPos + difference, buffer + endPos, r1 - difference - endPos); |
| 132 | memcpy(buffer + 15, newToken.data(), newToken.size()); |
| 133 | assert(buffer[endPos + difference] == '\r'); |
| 134 | assert(buffer[endPos + difference - 1] == newToken[newToken.size() - 1]); |
| 135 | } else { |
| 136 | std::cout << "could not fix auth token, not enough data available" << std::endl; |
| 137 | } |
| 138 | } else { |
no test coverage detected