sort.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /** --- BEGIN COPYRIGHT BLOCK ---
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. --- END COPYRIGHT BLOCK --- */
  6. /* DON'T SHIP THIS PROGRAM. It's terribly un-secure, as it
  7. enables an HTTP client to read the contents of any file.
  8. */
  9. /* This is a Gateway CGI program, for testing collation.
  10. It reads the text file named by $PATH_INFO and outputs its lines, sorted,
  11. in a table with the script and collation key computed by dsgw_strkeygen.
  12. The locale is controlled by the Accept-Language header in the HTTP request,
  13. like any Gateway CGI.
  14. */
  15. #include <errno.h>
  16. #include <stdio.h> /* fopen, fgets, perror */
  17. #include <stdlib.h> /* getenv, qsort */
  18. #include "dsgw.h"
  19. static const char*
  20. fgetln(FILE* f, int* error)
  21. {
  22. auto size_t buflen = 128;
  23. auto char* buf = dsgw_ch_malloc (buflen);
  24. *buf = '\0';
  25. while (fgets (buf, buflen, f)) {
  26. auto const size_t read = strlen(buf);
  27. if (buf[read-1] == '\n') {
  28. buf[read-1] = '\0';
  29. return buf;
  30. }
  31. buflen *= 2;
  32. buf = dsgw_ch_realloc (buf, buflen);
  33. }
  34. if (feof(f) && *buf) return buf;
  35. free (buf);
  36. return NULL;
  37. }
  38. typedef struct keystring {
  39. const char* ks_val;
  40. struct berval* ks_key;
  41. } keystring_t;
  42. static int
  43. keystring_cmp (const void* Lv, const void* Rv)
  44. {
  45. auto const keystring_t** L = (const keystring_t**)Lv;
  46. auto const keystring_t** R = (const keystring_t**)Rv;
  47. return dsgw_keycmp (NULL, (*L)->ks_key, (*R)->ks_key);
  48. }
  49. int
  50. main( int argc, char* argv[] )
  51. {
  52. auto int error = 0;
  53. auto const int reqmethod = dsgw_init (argc, argv, DSGW_METHOD_GET);
  54. auto char* fname = getenv ("PATH_INFO");
  55. dsgw_send_header();
  56. dsgw_emits ("<HTML>\n");
  57. dsgw_head_begin();
  58. dsgw_emits ("\n</head>\n<body>\n");
  59. if (!fname) {
  60. dsgw_emits ("!PATH_INFO\n");
  61. error = 1;
  62. } else {
  63. auto FILE* f = fopen (fname, "r");
  64. if (!f) {
  65. dsgw_emitf ("%s: errno %i\n", fname, errno);
  66. error = 2;
  67. } else {
  68. auto const char* line;
  69. auto keystring_t* v = NULL;
  70. auto size_t vlen = 0;
  71. while (line = fgetln(f, &error)) {
  72. v = (keystring_t*) dsgw_ch_realloc (v, (vlen+1) * sizeof(keystring_t));
  73. v[vlen].ks_val = line;
  74. v[vlen].ks_key = dsgw_strkeygen (CASE_INSENSITIVE, line);
  75. ++vlen;
  76. }
  77. fclose (f);
  78. if (vlen) {
  79. auto keystring_t** vp;
  80. auto size_t i;
  81. vp = (keystring_t**) dsgw_ch_malloc (vlen * sizeof(keystring_t*));
  82. for (i = 0; i < vlen; ++i) {
  83. vp[i] = v + i;
  84. }
  85. qsort (vp, vlen, sizeof(keystring_t*), keystring_cmp);
  86. dsgw_emits ("<table align=left cols=5>\n");
  87. dsgw_emits (" <tr>"
  88. "<th width=20>" DSGW_UTF8_NBSP "</th>"
  89. "<th align=left>line</th>"
  90. "<th width=25>script</th>"
  91. "<th width=20>" DSGW_UTF8_NBSP "</th>"
  92. "<th align=left>Sort Key</th>"
  93. "</tr>\n");
  94. for (i = 0; i < vlen; ++i) {
  95. auto size_t j;
  96. dsgw_emits (" <tr valign=baseline>");
  97. dsgw_emitf ("<th align=right>%lu:</th>", 1 + (unsigned long)(vp[i]-v));
  98. dsgw_emitf ("<td>%s</td>", vp[i]->ks_val);
  99. dsgw_emits ("<td align=center>");
  100. if (vp[i]->ks_key->bv_len) {
  101. dsgw_emitf ("%u", 0xFF & (unsigned)(vp[i]->ks_key->bv_val[0]));
  102. } else {
  103. dsgw_emits (DSGW_UTF8_NBSP);
  104. }
  105. dsgw_emits ("</td>");
  106. dsgw_emitf ("<td align=right>%lu:</td>", (unsigned long)(vp[i]->ks_key->bv_len) - 2);
  107. dsgw_emits ("<td><font size=\"-2\">");
  108. for (j = 1; j < vp[i]->ks_key->bv_len - 1; ++j) {
  109. dsgw_emitf ("%02x", 0xFF & (unsigned)(vp[i]->ks_key->bv_val[j]));
  110. }
  111. dsgw_emits ("</font></td>");
  112. dsgw_emits ("</tr>\n");
  113. }
  114. dsgw_emits ("</table>\n");
  115. free (vp);
  116. for (i = 0; i < vlen; ++i) {
  117. dsgw_keyfree (NULL, v[i].ks_key);
  118. }
  119. free (v);
  120. }
  121. }
  122. }
  123. dsgw_emits ("</body></HTML>\n");
  124. return error;
  125. }