Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

902 lines
26 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. openurl.c
  5. Abstract:
  6. Tests InternetOpenUrl()
  7. Author:
  8. Richard L Firth (rfirth) 29-May-1995
  9. Revision History:
  10. 29-May-1995 rfirth
  11. Created
  12. --*/
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <stdarg.h>
  16. #include <string.h>
  17. #include <io.h>
  18. #include <fcntl.h>
  19. #include <windows.h>
  20. #include <wininet.h>
  21. #include <catlib.h>
  22. #ifndef _CRTAPI1
  23. #define _CRTAPI1
  24. #endif
  25. #define IS_ARG(c) (((c) == '-') || ((c) == '/'))
  26. #define VERSION_STRING "1.0"
  27. #define URL_CONTEXT 0x55785875 // UxXu
  28. #define DEFAULT_BUFFER_LENGTH 1021 // odd number for fun!
  29. //
  30. // prototypes
  31. //
  32. void _CRTAPI1 main(int, char**);
  33. void usage(void);
  34. void _CRTAPI1 my_cleanup(void);
  35. void my_callback(HINTERNET, DWORD, DWORD, LPVOID, DWORD);
  36. void default_url_test(LPSTR, DWORD, DWORD);
  37. void open_urls(LPSTR*, int, LPSTR, DWORD, DWORD);
  38. void get_url_data(HINTERNET);
  39. void ftp_find(HINTERNET);
  40. void gopher_find(HINTERNET);
  41. void read_data(HINTERNET);
  42. void get_request_flags(HINTERNET);
  43. //
  44. // data
  45. //
  46. BOOL Verbose = FALSE;
  47. HINTERNET InternetHandle = NULL;
  48. INTERNET_STATUS_CALLBACK PreviousCallback;
  49. HINTERNET hCancel;
  50. BOOL AsyncMode = FALSE;
  51. HANDLE AsyncEvent = NULL;
  52. DWORD AsyncResult;
  53. DWORD AsyncError;
  54. BOOL UseQueryData = FALSE;
  55. BOOL NoDump = FALSE;
  56. DWORD BufferLength = DEFAULT_BUFFER_LENGTH;
  57. DWORD ReadLength = DEFAULT_BUFFER_LENGTH;
  58. LPSTR default_urls[] = {
  59. //
  60. // WEB
  61. //
  62. "http://www.microsoft.com",
  63. "http://www.microsoft.com/pages/misc/whatsnew.htm",
  64. //
  65. // gopher
  66. //
  67. "gopher://gopher.microsoft.com",
  68. "gopher://gopher.microsoft.com/11/msft/",
  69. "gopher://gopher.microsoft.com/00\\welcome.txt",
  70. "gopher://gopher.tc.umn.edu/11Information%20About%20Gopher%09%09%2B",
  71. "gopher://spinaltap.micro.umn.edu/11/computer",
  72. "gopher://mudhoney.micro.umn.edu:4325/7",
  73. "gopher://mudhoney.micro.umn.edu:4325/7%09gopher",
  74. "gopher://spinaltap.micro.umn.edu/7mindex:lotsoplaces%09gopher%09%2b",
  75. //
  76. // FTP
  77. //
  78. "ftp://ftp.microsoft.com",
  79. "ftp://ftp.microsoft.com/MSNBRO.TXT",
  80. "ftp://ftp.microsoft.com/Services/"
  81. };
  82. #define NUMBER_OF_DEFAULT_URLS (sizeof(default_urls)/sizeof(default_urls[0]))
  83. //
  84. // functions
  85. //
  86. void _CRTAPI1 main(int argc, char** argv) {
  87. BOOL ok;
  88. LPSTR urls[64];
  89. int numberOfUrls = 0;
  90. BOOL fCallback = FALSE;
  91. LPSTR headers = NULL;
  92. BOOL expectingHeaders = FALSE;
  93. DWORD accessMethod = INTERNET_OPEN_TYPE_PRECONFIG;
  94. LPSTR proxyServer = NULL;
  95. BOOL expectingProxy = FALSE;
  96. DWORD context = 0;
  97. DWORD flags = 0;
  98. LPSTR endptr;
  99. printf("\n"
  100. "OpenUrl Version " VERSION_STRING " " __DATE__ "\n"
  101. "\n"
  102. );
  103. for (--argc, ++argv; argc; --argc, ++argv) {
  104. if (IS_ARG(**argv)) {
  105. switch (tolower(*++*argv)) {
  106. case '?':
  107. usage();
  108. break;
  109. case 'a':
  110. ++*argv;
  111. if (**argv == 'l') {
  112. accessMethod = INTERNET_OPEN_TYPE_DIRECT;
  113. } else if (**argv == 'p') {
  114. accessMethod = INTERNET_OPEN_TYPE_PROXY;
  115. if (*++*argv) {
  116. proxyServer = *argv;
  117. } else {
  118. expectingProxy = TRUE;
  119. }
  120. } else {
  121. printf("error: unrecognised access type: '%c'\n", **argv);
  122. usage();
  123. }
  124. break;
  125. case 'b':
  126. BufferLength = (DWORD)strtol(++*argv, &endptr, 0);
  127. if (*endptr == 'K' || *endptr == 'k') {
  128. BufferLength *= 1024;
  129. }
  130. break;
  131. case 'c':
  132. fCallback = TRUE;
  133. break;
  134. case 'd':
  135. NoDump = TRUE;
  136. break;
  137. case 'e':
  138. flags |= INTERNET_FLAG_EXISTING_CONNECT;
  139. break;
  140. case 'h':
  141. if (*++*argv) {
  142. headers = *argv;
  143. } else {
  144. expectingHeaders = TRUE;
  145. }
  146. break;
  147. case 'l':
  148. ReadLength = (DWORD)strtol(++*argv, &endptr, 0);
  149. if (*endptr == 'K' || *endptr == 'k') {
  150. ReadLength *= 1024;
  151. }
  152. break;
  153. case 'n':
  154. flags |= INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE;
  155. break;
  156. case 'p':
  157. flags |= INTERNET_FLAG_PASSIVE;
  158. break;
  159. case 'q':
  160. UseQueryData = TRUE;
  161. break;
  162. case 'r':
  163. flags |= INTERNET_FLAG_RAW_DATA;
  164. break;
  165. case 'v':
  166. Verbose = TRUE;
  167. break;
  168. case 'x':
  169. context = URL_CONTEXT;
  170. break;
  171. case 'y':
  172. AsyncMode = TRUE;
  173. break;
  174. default:
  175. printf("unknown command line flag: '%c'\n", **argv);
  176. usage();
  177. }
  178. } else if (expectingProxy) {
  179. proxyServer = *argv;
  180. expectingProxy = FALSE;
  181. } else if (expectingHeaders) {
  182. headers = *argv;
  183. expectingHeaders = FALSE;
  184. } else {
  185. if (numberOfUrls == sizeof(urls)/sizeof(urls[0]) - 1) {
  186. break;
  187. }
  188. urls[numberOfUrls++] = *argv;
  189. }
  190. }
  191. if (BufferLength < ReadLength) {
  192. BufferLength = ReadLength;
  193. }
  194. //
  195. // exit function
  196. //
  197. atexit(my_cleanup);
  198. if (AsyncMode) {
  199. //
  200. // create an auto-reset, initially unsignalled event
  201. //
  202. AsyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  203. if (!AsyncEvent) {
  204. print_error("OpenUrl", "CreateEvent()");
  205. exit(1);
  206. }
  207. }
  208. //
  209. // get a handle to the internet - local, gateway or CERN proxy
  210. //
  211. InternetHandle = InternetOpen("OpenUrl",
  212. accessMethod,
  213. proxyServer,
  214. NULL,
  215. AsyncMode ? INTERNET_FLAG_ASYNC : 0
  216. );
  217. if (InternetHandle == NULL) {
  218. print_error("openurl()", "InternetOpen()");
  219. exit(1);
  220. }
  221. if (Verbose) {
  222. printf("InternetOpen() returns handle %x\n", InternetHandle);
  223. }
  224. //
  225. // let's have a status callback
  226. //
  227. if (fCallback) {
  228. PreviousCallback = InternetSetStatusCallback(InternetHandle, my_callback);
  229. if (Verbose) {
  230. printf("previous Internet callback = %x\n", PreviousCallback);
  231. }
  232. }
  233. if (numberOfUrls == 0) {
  234. default_url_test(headers, flags, context);
  235. } else {
  236. open_urls(urls, numberOfUrls, headers, flags, context);
  237. }
  238. if (Verbose) {
  239. printf("closing InternetHandle (%x)\n", InternetHandle);
  240. }
  241. ok = InternetCloseHandle(InternetHandle);
  242. if (!ok) {
  243. print_error("openurl()", "InternetClose(%x)", InternetHandle);
  244. exit(1);
  245. } else {
  246. InternetHandle = NULL;
  247. }
  248. printf("Done.\n");
  249. exit(0);
  250. }
  251. void usage() {
  252. printf("\n"
  253. "usage: openurl [-a{l|p}[[ ]{server[:port]}] [-b#] [-c] [-d] [-h[ ]{headers}]\n"
  254. " [-l#] [-n] [-p] [-q] [-r] [-v] [-x] [-y] [url]*\n"
  255. "\n"
  256. "where: -al = local internet access\n"
  257. " -ap = CERN proxy internet access\n"
  258. " -b = buffer size\n"
  259. " -c = enable status callbacks\n"
  260. " -d = don't dump data\n"
  261. " -e = use existing connection\n"
  262. " -h = headers\n"
  263. " -l = read length\n"
  264. " -n = don't use cache\n"
  265. " -p = PASSIVE mode (FTP transfers)\n"
  266. " -q = use InternetQueryDataAvailable\n"
  267. " -r = raw data. Default is HTML for FTP and gopher directories\n"
  268. " -v = Verbose mode\n"
  269. " -x = use context value when calling InternetOpenUrl()\n"
  270. " -y = Async mode\n"
  271. "\n"
  272. " server = gateway server or proxy server name\n"
  273. " :port = (optional) CERN proxy port\n"
  274. " url = one or more URLs to open\n"
  275. "\n"
  276. "Default internet access is pre-configured (i.e. use settings in registry)\n"
  277. );
  278. exit(1);
  279. }
  280. void _CRTAPI1 my_cleanup() {
  281. if (InternetHandle != NULL) {
  282. if (Verbose) {
  283. printf("closing Internet handle %x\n", InternetHandle);
  284. }
  285. if (!InternetCloseHandle(InternetHandle)) {
  286. print_error("my_cleanup", "InternetCloseHandle(%x)", InternetHandle);
  287. }
  288. }
  289. }
  290. VOID
  291. my_callback(
  292. HINTERNET hInternet,
  293. DWORD Context,
  294. DWORD Status,
  295. LPVOID Info,
  296. DWORD Length
  297. )
  298. {
  299. char* type$;
  300. DWORD handleType;
  301. DWORD size;
  302. size = sizeof(handleType);
  303. if (!InternetQueryOption(hInternet,
  304. INTERNET_OPTION_HANDLE_TYPE,
  305. (LPVOID)&handleType,
  306. &size)) {
  307. print_error("my_callback", "InternetQueryOption(HANDLE_TYPE)");
  308. } else {
  309. switch (handleType) {
  310. case INTERNET_HANDLE_TYPE_INTERNET:
  311. type$ = "Internet";
  312. break;
  313. case INTERNET_HANDLE_TYPE_CONNECT_FTP:
  314. type$ = "FTP Connect";
  315. break;
  316. case INTERNET_HANDLE_TYPE_CONNECT_GOPHER:
  317. type$ = "Gopher Connect";
  318. break;
  319. case INTERNET_HANDLE_TYPE_CONNECT_HTTP:
  320. type$ = "HTTP Connect";
  321. break;
  322. case INTERNET_HANDLE_TYPE_FTP_FIND:
  323. type$ = "FTP Find";
  324. break;
  325. case INTERNET_HANDLE_TYPE_FTP_FIND_HTML:
  326. type$ = "FTP Find HTML";
  327. break;
  328. case INTERNET_HANDLE_TYPE_FTP_FILE:
  329. type$ = "FTP File";
  330. break;
  331. case INTERNET_HANDLE_TYPE_FTP_FILE_HTML:
  332. type$ = "FTP File HTML";
  333. break;
  334. case INTERNET_HANDLE_TYPE_GOPHER_FIND:
  335. type$ = "Gopher Find";
  336. break;
  337. case INTERNET_HANDLE_TYPE_GOPHER_FIND_HTML:
  338. type$ = "Gopher Find HTML";
  339. break;
  340. case INTERNET_HANDLE_TYPE_GOPHER_FILE:
  341. type$ = "Gopher File";
  342. break;
  343. case INTERNET_HANDLE_TYPE_GOPHER_FILE_HTML:
  344. type$ = "Gopher File HTML";
  345. type$ = "Internet";
  346. break;
  347. case INTERNET_HANDLE_TYPE_HTTP_REQUEST:
  348. type$ = "HTTP Request";
  349. break;
  350. default:
  351. type$ = "???";
  352. }
  353. printf("callback: handle %x = %s\n", hInternet, type$);
  354. }
  355. switch (Status) {
  356. case INTERNET_STATUS_RESOLVING_NAME:
  357. type$ = "RESOLVING NAME";
  358. break;
  359. case INTERNET_STATUS_NAME_RESOLVED:
  360. type$ = "NAME RESOLVED";
  361. break;
  362. case INTERNET_STATUS_CONNECTING_TO_SERVER:
  363. type$ = "CONNECTING TO SERVER";
  364. break;
  365. case INTERNET_STATUS_CONNECTED_TO_SERVER:
  366. type$ = "CONNECTED TO SERVER";
  367. break;
  368. case INTERNET_STATUS_SENDING_REQUEST:
  369. type$ = "SENDING REQUEST";
  370. break;
  371. case INTERNET_STATUS_REQUEST_SENT:
  372. type$ = "REQUEST SENT";
  373. break;
  374. case INTERNET_STATUS_RECEIVING_RESPONSE:
  375. type$ = "RECEIVING RESPONSE";
  376. break;
  377. case INTERNET_STATUS_RESPONSE_RECEIVED:
  378. type$ = "RESPONSE RECEIVED";
  379. break;
  380. case INTERNET_STATUS_CLOSING_CONNECTION:
  381. type$ = "CLOSING CONNECTION";
  382. break;
  383. case INTERNET_STATUS_CONNECTION_CLOSED:
  384. type$ = "CONNECTION CLOSED";
  385. break;
  386. case INTERNET_STATUS_HANDLE_CREATED:
  387. type$ = "HANDLE CREATED";
  388. hCancel = *(LPHINTERNET)Info;
  389. break;
  390. case INTERNET_STATUS_HANDLE_CLOSING:
  391. type$ = "HANDLE CLOSING";
  392. break;
  393. case INTERNET_STATUS_REQUEST_COMPLETE:
  394. type$ = "REQUEST COMPLETE";
  395. AsyncResult = ((LPINTERNET_ASYNC_RESULT)Info)->dwResult;
  396. AsyncError = ((LPINTERNET_ASYNC_RESULT)Info)->dwError;
  397. break;
  398. default:
  399. type$ = "???";
  400. break;
  401. }
  402. if (Verbose) {
  403. printf("callback: handle %x [context %x [%s]] %s ",
  404. hInternet,
  405. Context,
  406. (Context == URL_CONTEXT) ? "UrlContext" : "???",
  407. type$
  408. );
  409. if (Info) {
  410. if ((Status == INTERNET_STATUS_HANDLE_CREATED)
  411. || (Status == INTERNET_STATUS_HANDLE_CLOSING)) {
  412. printf("%x", *(LPHINTERNET)Info);
  413. } else if (Length == sizeof(DWORD)) {
  414. printf("%d", *(LPDWORD)Info);
  415. } else if (Status != INTERNET_STATUS_REQUEST_COMPLETE) {
  416. printf(Info);
  417. }
  418. }
  419. putchar('\n');
  420. }
  421. if (Status == INTERNET_STATUS_REQUEST_COMPLETE) {
  422. if (AsyncMode) {
  423. SetEvent(AsyncEvent);
  424. } else {
  425. printf("error: INTERNET_STATUS_REQUEST_COMPLETE received when not async\n");
  426. }
  427. }
  428. }
  429. void default_url_test(LPSTR headers, DWORD flags, DWORD context) {
  430. open_urls(default_urls, NUMBER_OF_DEFAULT_URLS, headers, flags, context);
  431. }
  432. void open_urls(LPSTR* purls, int nurls, LPSTR headers, DWORD flags, DWORD context) {
  433. HINTERNET handle;
  434. if (headers) {
  435. LPSTR h;
  436. for (h = headers; *h; ++h) {
  437. if (*h == '\\' && *(h + 1) == 'n') {
  438. *h++ = '\r';
  439. *h = '\n';
  440. }
  441. }
  442. }
  443. while (nurls--) {
  444. if (Verbose) {
  445. printf("\nopening URL \"%s\"\n\n", *purls);
  446. }
  447. handle = InternetOpenUrl(InternetHandle,
  448. *purls,
  449. headers,
  450. headers ? -1 : 0,
  451. flags,
  452. context
  453. );
  454. if ((handle == NULL) && AsyncMode) {
  455. DWORD err;
  456. err = GetLastError();
  457. if (err == ERROR_IO_PENDING) {
  458. if (Verbose) {
  459. printf("waiting for async InternetOpenUrl()...\n");
  460. }
  461. WaitForSingleObject(AsyncEvent, INFINITE);
  462. handle = (HINTERNET)AsyncResult;
  463. SetLastError(AsyncError);
  464. }
  465. } else if (AsyncMode && Verbose) {
  466. printf("async InternetOpenUrl() returns sync result\n");
  467. }
  468. if (handle == NULL) {
  469. print_error("open_urls", "InternetOpenUrl(%s)", *purls);
  470. } else {
  471. if (Verbose) {
  472. printf("InternetOpenUrl() returns handle %x\n", handle);
  473. }
  474. get_request_flags(handle);
  475. get_url_data(handle);
  476. }
  477. ++purls;
  478. }
  479. }
  480. void get_url_data(HINTERNET handle) {
  481. DWORD handleType;
  482. DWORD handleTypeLen;
  483. handleTypeLen = sizeof(handleType);
  484. if (InternetQueryOption(handle,
  485. INTERNET_OPTION_HANDLE_TYPE,
  486. (LPVOID)&handleType,
  487. &handleTypeLen
  488. )) {
  489. switch (handleType) {
  490. case INTERNET_HANDLE_TYPE_INTERNET:
  491. printf("error: get_url_data: HANDLE_TYPE_INTERNET?\n");
  492. break;
  493. case INTERNET_HANDLE_TYPE_CONNECT_FTP:
  494. printf("error: get_url_data: INTERNET_HANDLE_TYPE_CONNECT_FTP?\n");
  495. break;
  496. case INTERNET_HANDLE_TYPE_CONNECT_GOPHER:
  497. printf("error: get_url_data: INTERNET_HANDLE_TYPE_CONNECT_GOPHER?\n");
  498. break;
  499. case INTERNET_HANDLE_TYPE_CONNECT_HTTP:
  500. printf("error: get_url_data: INTERNET_HANDLE_TYPE_CONNECT_HTTP?\n");
  501. break;
  502. case INTERNET_HANDLE_TYPE_FTP_FIND:
  503. ftp_find(handle);
  504. break;
  505. case INTERNET_HANDLE_TYPE_GOPHER_FIND:
  506. gopher_find(handle);
  507. break;
  508. case INTERNET_HANDLE_TYPE_FTP_FIND_HTML:
  509. case INTERNET_HANDLE_TYPE_FTP_FILE:
  510. case INTERNET_HANDLE_TYPE_FTP_FILE_HTML:
  511. case INTERNET_HANDLE_TYPE_GOPHER_FIND_HTML:
  512. case INTERNET_HANDLE_TYPE_GOPHER_FILE:
  513. case INTERNET_HANDLE_TYPE_GOPHER_FILE_HTML:
  514. case INTERNET_HANDLE_TYPE_HTTP_REQUEST:
  515. read_data(handle);
  516. break;
  517. default:
  518. printf("error: get_url_data: handleType == %d?\n", handleType);
  519. break;
  520. }
  521. if (Verbose) {
  522. printf("closing Internet handle %x\n", handle);
  523. }
  524. if (!InternetCloseHandle(handle)) {
  525. print_error("get_url_data", "InternetCloseHandle(%x)", handle);
  526. }
  527. } else {
  528. print_error("get_url_data", "InternetQueryOption()");
  529. }
  530. }
  531. void ftp_find(HINTERNET handle) {
  532. WIN32_FIND_DATA data;
  533. BOOL ok;
  534. do {
  535. SYSTEMTIME systemTime;
  536. ok = InternetFindNextFile(handle, (LPVOID)&data);
  537. if (!ok) {
  538. if (AsyncMode) {
  539. if (GetLastError() == ERROR_IO_PENDING) {
  540. if (Verbose) {
  541. printf("waiting for async InternetFindNextFile()...\n");
  542. }
  543. WaitForSingleObject(AsyncEvent, INFINITE);
  544. ok = (BOOL)AsyncResult;
  545. SetLastError(AsyncError);
  546. }
  547. }
  548. }
  549. if (ok && !NoDump) {
  550. if (!FileTimeToSystemTime(&data.ftLastWriteTime, &systemTime)) {
  551. print_error("ftp_find", "FileTimeToSystemTime()");
  552. }
  553. printf("%2d-%02d-%04d %2d:%02d:%02d %15d bytes %-s%-s%-s %s\n",
  554. systemTime.wMonth,
  555. systemTime.wDay,
  556. systemTime.wYear,
  557. systemTime.wHour,
  558. systemTime.wMinute,
  559. systemTime.wSecond,
  560. data.nFileSizeLow,
  561. (data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL)
  562. ? "Normal " : "",
  563. (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
  564. ? "ReadOnly " : "",
  565. (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  566. ? "Directory " : "",
  567. data.cFileName
  568. );
  569. }
  570. } while (ok);
  571. if (GetLastError() != ERROR_NO_MORE_FILES) {
  572. print_error("ftp_find", "InternetFindNextFile()");
  573. }
  574. }
  575. void gopher_find(HINTERNET handle) {
  576. GOPHER_FIND_DATA data;
  577. BOOL ok;
  578. int i;
  579. i = 0;
  580. do {
  581. ok = InternetFindNextFile(handle, (LPVOID)&data);
  582. if (!ok) {
  583. if (AsyncMode) {
  584. if (GetLastError() == ERROR_IO_PENDING) {
  585. if (Verbose) {
  586. printf("waiting for async InternetFindNextFile()...\n");
  587. }
  588. WaitForSingleObject(AsyncEvent, INFINITE);
  589. ok = (BOOL)AsyncResult;
  590. SetLastError(AsyncError);
  591. }
  592. }
  593. }
  594. if (ok && !NoDump) {
  595. LPGOPHER_FIND_DATA p;
  596. SYSTEMTIME systemTime;
  597. char timeBuf[9];
  598. char sizeBuf[32];
  599. p = (LPGOPHER_FIND_DATA)&data;
  600. if ((p->LastModificationTime.dwLowDateTime != 0)
  601. && (p->LastModificationTime.dwHighDateTime != 0)) {
  602. FileTimeToSystemTime(&p->LastModificationTime, &systemTime);
  603. sprintf(timeBuf,
  604. "%02d-%02d-%02d",
  605. systemTime.wMonth,
  606. systemTime.wDay,
  607. systemTime.wYear % 100
  608. );
  609. sprintf(sizeBuf, "%d", p->SizeLow);
  610. } else {
  611. timeBuf[0] = '\0';
  612. sizeBuf[0] = '\0';
  613. }
  614. printf("%5d %c %7s %10s %8s %s\n",
  615. i,
  616. (p->GopherType & GOPHER_TYPE_GOPHER_PLUS) ? '+' : ' ',
  617. (p->GopherType & GOPHER_TYPE_TEXT_FILE) ? "Text"
  618. : (p->GopherType & GOPHER_TYPE_DIRECTORY) ? "Dir"
  619. : (p->GopherType & GOPHER_TYPE_CSO) ? "Phone"
  620. : (p->GopherType & GOPHER_TYPE_ERROR) ? "Error"
  621. : (p->GopherType & GOPHER_TYPE_MAC_BINHEX) ? "MAC"
  622. : (p->GopherType & GOPHER_TYPE_DOS_ARCHIVE) ? "Archive"
  623. : (p->GopherType & GOPHER_TYPE_UNIX_UUENCODED) ? "UNIX"
  624. : (p->GopherType & GOPHER_TYPE_INDEX_SERVER) ? "Index"
  625. : (p->GopherType & GOPHER_TYPE_TELNET) ? "Telnet"
  626. : (p->GopherType & GOPHER_TYPE_BINARY) ? "Binary"
  627. : (p->GopherType & GOPHER_TYPE_REDUNDANT) ? "Backup"
  628. : (p->GopherType & GOPHER_TYPE_TN3270) ? "TN3270"
  629. : (p->GopherType & GOPHER_TYPE_GIF) ? "GIF"
  630. : (p->GopherType & GOPHER_TYPE_IMAGE) ? "Image"
  631. : (p->GopherType & GOPHER_TYPE_BITMAP) ? "Bitmap"
  632. : (p->GopherType & GOPHER_TYPE_MOVIE) ? "Movie"
  633. : (p->GopherType & GOPHER_TYPE_SOUND) ? "Sound"
  634. : (p->GopherType & GOPHER_TYPE_HTML) ? "HTML"
  635. : (p->GopherType & GOPHER_TYPE_PDF) ? "PDF"
  636. : (p->GopherType & GOPHER_TYPE_CALENDAR) ? "Cal"
  637. : (p->GopherType & GOPHER_TYPE_INLINE) ? "Inline"
  638. : (p->GopherType & GOPHER_TYPE_UNKNOWN) ? "Unknown"
  639. : "\a????",
  640. sizeBuf,
  641. timeBuf,
  642. p->DisplayString
  643. );
  644. ++i;
  645. }
  646. } while (ok);
  647. if (GetLastError() != ERROR_NO_MORE_FILES) {
  648. print_error("gopher_find", "InternetFindNextFile()");
  649. }
  650. }
  651. void read_data(HINTERNET handle) {
  652. char* buf;
  653. DWORD nread;
  654. BOOL ok;
  655. int mode;
  656. buf = (char*)malloc(BufferLength);
  657. if (!buf) {
  658. printf("error: failed to allocate %d bytes for buffer\n", BufferLength);
  659. return;
  660. }
  661. mode = _setmode(1, _O_BINARY);
  662. do {
  663. DWORD avail;
  664. int i;
  665. if (UseQueryData) {
  666. ok = InternetQueryDataAvailable(handle, &avail, 0, 0);
  667. if (!ok) {
  668. if (GetLastError() == ERROR_IO_PENDING) {
  669. if (Verbose) {
  670. printf("waiting for async InternetQueryDataAvailable()...\n");
  671. }
  672. WaitForSingleObject(AsyncEvent, INFINITE);
  673. ok = (BOOL)AsyncResult;
  674. SetLastError(AsyncError);
  675. }
  676. }
  677. if (!ok) {
  678. print_error("read_file", "InternetQueryDataAvailable()");
  679. break;
  680. }
  681. if (Verbose) {
  682. printf("InternetQueryDataAvailable() returns %d bytes\n", avail);
  683. }
  684. } else {
  685. avail = BufferLength;
  686. }
  687. avail = min(avail, ReadLength);
  688. for (i = 0; i < 2; ++i) {
  689. memset(buf, '@', avail);
  690. ok = InternetReadFile(handle, buf, avail, &nread);
  691. if (!ok) {
  692. if (AsyncMode) {
  693. if (GetLastError() == ERROR_IO_PENDING) {
  694. if (Verbose) {
  695. printf("waiting for async InternetFindNextFile()...\n");
  696. }
  697. WaitForSingleObject(AsyncEvent, INFINITE);
  698. ok = (BOOL)AsyncResult;
  699. SetLastError(AsyncError);
  700. }
  701. } else {
  702. break;
  703. }
  704. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  705. if (i == 1) {
  706. printf("error: failed to read %d bytes in 2 attempts\n",
  707. nread);
  708. goto quit;
  709. }
  710. //
  711. // second attempt with all buffer
  712. //
  713. avail = BufferLength;
  714. } else {
  715. break;
  716. }
  717. }
  718. }
  719. if (ok && !NoDump) {
  720. if (!nread) {
  721. printf("=== end of file ===\n");
  722. } else {
  723. _write(1, buf, nread);
  724. }
  725. } else if (ok && NoDump && Verbose) {
  726. printf("InternetReadFile() returns %d bytes\n", nread);
  727. }
  728. } while (ok && nread);
  729. if (GetLastError() != ERROR_SUCCESS) {
  730. print_error("read_file", "InternetReadFile()");
  731. }
  732. quit:
  733. free(buf);
  734. _setmode(1, mode);
  735. }
  736. void get_request_flags(HINTERNET hInternet) {
  737. DWORD dwFlags;
  738. DWORD len = sizeof(dwFlags);
  739. if (InternetQueryOption(hInternet,
  740. INTERNET_OPTION_REQUEST_FLAGS,
  741. &dwFlags,
  742. &len)) {
  743. char buf[256];
  744. char * p = buf;
  745. p += sprintf(p, "REQUEST_FLAGS = %08x\n", dwFlags);
  746. p += sprintf(p, "\tRetrieved from: %s\n",
  747. (dwFlags & INTERNET_REQFLAG_FROM_CACHE) ? "Cache" : "Network");
  748. p += sprintf(p, "\tNo Headers: %s\n",
  749. (dwFlags & INTERNET_REQFLAG_NO_HEADERS) ? "TRUE" : "FALSE");
  750. p += sprintf(p, "\tVia Proxy: %s\n",
  751. (dwFlags & INTERNET_REQFLAG_VIA_PROXY) ? "YES" : "NO");
  752. printf(buf);
  753. } else {
  754. print_error("get_request_flags()", "InternetQueryOption()");
  755. }
  756. }