#include <cups/string.h>
#include <cups/file.h>
#include <cups/http.h>
#include <cups/i18n.h>
#include <stdlib.h>
#include <unistd.h>
int save_messages(cups_array_t *cat, const char *filename);
int translate_messages(cups_array_t *cat, const char *lang);
int write_string(cups_file_t *fp, const char *s);
int
main(int argc,
char *argv[])
{
cups_array_t *cat;
if (argc != 3)
{
fputs("Usage: translate cups_language.po language\n", stderr);
return (1);
}
if (access(argv[1], 0))
cat = _cupsMessageLoad("cups.pot", 1);
else
cat = _cupsMessageLoad(argv[1], 1);
if (!cat)
{
puts("Unable to load message catalog.");
return (1);
}
if (!translate_messages(cat, argv[2]))
{
puts("Unable to translate message catalog.");
return (1);
}
if (!save_messages(cat, argv[1]))
{
puts("Unable to save message catalog.");
return (1);
}
return (0);
}
int
save_messages(cups_array_t *cat,
const char *filename)
{
_cups_message_t *m;
cups_file_t *fp;
if ((fp = cupsFileOpen(filename, "w")) == NULL)
return (0);
for (m = (_cups_message_t *)cupsArrayFirst(cat);
m;
m = (_cups_message_t *)cupsArrayNext(cat))
{
if (cupsFilePuts(fp, "msgid \"") < 0)
break;
if (!write_string(fp, m->id))
break;
if (cupsFilePuts(fp, "\"\nmsgstr \"") < 0)
break;
if (m->str)
{
if (!write_string(fp, m->str))
break;
}
if (cupsFilePuts(fp, "\"\n") < 0)
break;
}
cupsFileClose(fp);
return (!m);
}
int
translate_messages(cups_array_t *cat,
const char *lang)
{
int ret;
_cups_message_t *m;
int tries;
http_t *http;
http_status_t status;
char *idptr,
buffer[65536],
*bufptr,
*bufend,
length[16];
int bytes;
puts("Connecting to translate.google.com...");
if ((http = httpConnect("translate.google.com", 80)) == NULL)
{
perror("Unable to connect to translate.google.com");
return (0);
}
for (m = (_cups_message_t *)cupsArrayFirst(cat), ret = 1;
m;
m = (_cups_message_t *)cupsArrayNext(cat))
{
if (m->str && m->str[0])
continue;
snprintf(buffer, sizeof(buffer),
"hl=en&ie=UTF8&langpair=en|%s&oe=UTF8&text=", lang);
bufptr = buffer + strlen(buffer);
bufend = buffer + sizeof(buffer) - 5;
for (idptr = m->id; *idptr && bufptr < bufend; idptr ++)
if (*idptr == ' ')
*bufptr++ = '+';
else if (*idptr < ' ' || *idptr == '%')
{
sprintf(bufptr, "%%%02X", *idptr & 255);
bufptr += 3;
}
else if (*idptr != '&')
*bufptr++ = *idptr;
*bufptr++ = '&';
*bufptr = '\0';
sprintf(length, "%d", (int)(bufptr - buffer));
printf("\"%s\" = ", m->id);
fflush(stdout);
tries = 0;
do
{
httpClearFields(http);
httpSetField(http, HTTP_FIELD_CONTENT_TYPE,
"application/x-www-form-urlencoded");
httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length);
if (httpPost(http, "/translate_t"))
{
httpReconnect(http);
httpPost(http, "/translate_t");
}
httpWrite2(http, buffer, bufptr - buffer);
while ((status = httpUpdate(http)) == HTTP_CONTINUE);
if (status != HTTP_OK && status != HTTP_ERROR)
httpFlush(http);
tries ++;
}
while (status == HTTP_ERROR && tries < 10);
if (status == HTTP_OK)
{
bufptr = buffer;
bufend = buffer + sizeof(buffer) - 1;
while ((bytes = httpRead2(http, bufptr, bufend - bufptr)) > 0)
bufptr += bytes;
if (bytes < 0)
{
puts("READ ERROR!");
ret = 0;
break;
}
*bufptr = '\0';
if ((bufptr = strstr(buffer, "<div id=result_box")) == NULL)
{
puts("NO div id=result_box!");
ret = 0;
break;
}
if ((bufptr = strchr(bufptr, '>')) == NULL)
{
puts("DIV SHORT DATA!");
ret = 0;
break;
}
bufptr ++;
if ((bufend = strstr(bufptr, "</div>")) == NULL)
{
puts("/DIV SHORT DATA!");
ret = 0;
break;
}
*bufend = '\0';
m->str = strdup(bufptr);
for (bufptr = strchr(m->str, '&');
bufptr;
bufptr = strchr(bufptr + 1, '&'))
{
if (!strncmp(bufptr, "<", 4))
{
*bufptr = '<';
_cups_strcpy(bufptr + 1, bufptr + 4);
}
else if (!strncmp(bufptr, ">", 4))
{
*bufptr = '>';
_cups_strcpy(bufptr + 1, bufptr + 4);
}
else if (!strncmp(bufptr, "&", 5))
_cups_strcpy(bufptr + 1, bufptr + 5);
}
printf("\"%s\"\n", m->str);
}
else if (status == HTTP_ERROR)
{
printf("NETWORK ERROR (%s)!\n", strerror(httpError(http)));
ret = 0;
break;
}
else
{
printf("HTTP ERROR %d!\n", status);
ret = 0;
break;
}
}
httpClose(http);
return (ret);
}
int
write_string(cups_file_t *fp,
const char *s)
{
while (*s)
{
switch (*s)
{
case '\n' :
if (cupsFilePuts(fp, "\\n") < 0)
return (0);
break;
case '\r' :
if (cupsFilePuts(fp, "\\r") < 0)
return (0);
break;
case '\t' :
if (cupsFilePuts(fp, "\\t") < 0)
return (0);
break;
case '\\' :
if (cupsFilePuts(fp, "\\\\") < 0)
return (0);
break;
case '\"' :
if (cupsFilePuts(fp, "\\\"") < 0)
return (0);
break;
default :
if ((*s & 255) < ' ')
{
if (cupsFilePrintf(fp, "\\%o", *s) < 0)
return (0);
}
else if (cupsFilePutChar(fp, *s) < 0)
return (0);
break;
}
s ++;
}
return (1);
}