?login_element?

Subversion Repositories NedoOS

Rev

Rev 1998 | Rev 2025 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

  1. #include <math.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <oscalls.h>
  6. #include <osfs.h>
  7. #include <intrz80.h>
  8. #include <ctype.h>
  9. #include <tcp.h>
  10. #include <graphic.h>
  11. #include <terminal.c>
  12. #define COMMANDLINE 0x0080
  13. unsigned char ver[] = "1.9";
  14. unsigned char queryType[64];
  15. unsigned char netbuf[1452];
  16. unsigned char dataBuffer[6096];
  17. unsigned char crlf[2] = {13, 10};
  18. unsigned char formats[4][4] = {"pt3", "pt2", "tfc", "ts"};
  19. unsigned char status, key, curFormat;
  20. struct sockaddr_in targetadr;
  21. struct readstructure readStruct;
  22. unsigned long contLen;
  23. long count;
  24. unsigned char saveFlag, saveBak, logFlag, rptFlag;
  25. union APP_PAGES main_pg;
  26. union APP_PAGES player_pg;
  27. extern void dns_resolve(void);
  28.  
  29. struct fileStruct
  30. {
  31.   long picId;
  32.   unsigned long fileSize;
  33.   unsigned int picYear;
  34.   unsigned long totalAmount;
  35.   unsigned int curPos;
  36.   unsigned int startBar;
  37.   unsigned int trackInSeconds;
  38.   unsigned char time[16];
  39.   unsigned char picRating[8];
  40.   unsigned char trackName[256];
  41.   unsigned char fileName[256];
  42.   unsigned char authorIds[64];
  43.   unsigned char authorTitle[64];
  44.   unsigned char authorRealName[64];
  45.   unsigned char afn[64];
  46.   unsigned char tfn[64];
  47.   unsigned char fileName2[256];
  48. } curFileStruct;
  49.  
  50. void delay(unsigned long counter)
  51. {
  52.   unsigned long start, finish;
  53.   counter = counter / 20;
  54.   if (counter < 1)
  55.   {
  56.     counter = 1;
  57.   }
  58.   start = time();
  59.   finish = start + counter;
  60.  
  61.   while (start < finish)
  62.   {
  63.     start = time();
  64.     YIELD();
  65.   }
  66. }
  67.  
  68. void clearStatus(void)
  69. {
  70.   AT(1, 25);
  71.   printf("                                                                               \r");
  72. }
  73.  
  74. void printProgress(unsigned char type)
  75. {
  76.   unsigned char bar, minutes, seconds;
  77.   unsigned char *position;
  78.   long barLenght;
  79.   int timer;
  80.   switch (type)
  81.   {
  82.   case 0: // print empty bar
  83.     AT(6, 11);
  84.     ATRIB(93);
  85.     printf("%02u:%02u", 0, 0);
  86.     AT(15, 11);
  87.     ATRIB(97);
  88.     for (bar = 0; bar < 50; bar++)
  89.     {
  90.       putchar(176);
  91.     }
  92.     putchar(' ');
  93.     putchar(' ');
  94.     minutes = atoi(curFileStruct.time);
  95.     position = (strstr(curFileStruct.time, ":")) + 1;
  96.     seconds = atoi(position);
  97.     curFileStruct.trackInSeconds = minutes * 60 + seconds;
  98.     curFileStruct.curPos = 0;
  99.     curFileStruct.startBar = 0;
  100.     break;
  101.   case 1: // print progress bar
  102.  
  103.     AT(6, 11);
  104.     ATRIB(93);
  105.     timer = floor(curFileStruct.curPos / 60);
  106.     printf("%02u:%02u", timer, (curFileStruct.curPos - (timer * 60)));
  107.  
  108.     barLenght = (curFileStruct.curPos * 50 / curFileStruct.trackInSeconds);
  109.     if (barLenght > 49)
  110.     {
  111.       barLenght = 50;
  112.     }
  113.     AT(15 + curFileStruct.startBar, 11);
  114.     ATRIB(97);
  115.     for (bar = 0; bar < barLenght - curFileStruct.startBar; bar++)
  116.     {
  117.       putchar(178);
  118.     }
  119.     AT(1, 1);
  120.     curFileStruct.startBar = bar;
  121.     break;
  122.   case 2: // print full bar
  123.     AT(15, 11);
  124.     ATRIB(97);
  125.     for (bar = 0; bar < 50; bar++)
  126.     {
  127.       putchar(178);
  128.     }
  129.     break;
  130.   }
  131. }
  132. void errorPrint(unsigned int error)
  133. {
  134.   switch (error)
  135.   {
  136.   case 2:
  137.     printf("02 SHUT_RDWR");
  138.     break;
  139.   case 4:
  140.     printf("04 ERR_INTR");
  141.     break;
  142.   case 23:
  143.     printf("23 ERR_NFILE");
  144.     break;
  145.   case 35:
  146.     printf("35 ERR_EAGAIN");
  147.     break;
  148.   case 37:
  149.     printf("37 ERR_ALREADY");
  150.     break;
  151.   case 38:
  152.     printf("38 ERR_NOTSOCK");
  153.     break;
  154.   case 40:
  155.     printf("40 ERR_EMSGSIZE");
  156.     break;
  157.   case 41:
  158.     printf("41 ERR_PROTOTYPE");
  159.     break;
  160.   case 47:
  161.     printf("47 ERR_AFNOSUPPORT");
  162.     break;
  163.   case 53:
  164.     printf("53 ERR_ECONNABORTED");
  165.     break;
  166.   case 54:
  167.     printf("54 ERR_CONNRESET");
  168.     break;
  169.   case 57:
  170.     printf("57 ERR_NOTCONN");
  171.     break;
  172.   case 65:
  173.     printf("65 ERR_HOSTUNREACH");
  174.     break;
  175.   default:
  176.     printf("%u UNKNOWN ERROR", error);
  177.     break;
  178.   }
  179.   YIELD();
  180. }
  181.  
  182. unsigned char OpenSock(unsigned char family, unsigned char protocol)
  183. {
  184.   unsigned char socket;
  185.   unsigned int todo;
  186.   todo = OS_NETSOCKET((family << 8) + protocol);
  187.   if (todo > 32767)
  188.   {
  189.     clearStatus();
  190.     printf("OS_NETSOCKET: ");
  191.     errorPrint(todo & 255);
  192.     exit(0);
  193.   }
  194.   else
  195.   {
  196.     socket = ((todo & 65280) >> 8);
  197.     if (logFlag)
  198.     {
  199.       clearStatus();
  200.       printf("OS_NETSOCKET: Socket #%d created.", socket);
  201.     }
  202.   }
  203.   return socket;
  204. }
  205.  
  206. unsigned int netShutDown(unsigned char socket, unsigned char type)
  207. {
  208.   unsigned int todo;
  209.   todo = OS_NETSHUTDOWN(socket, type);
  210.   if (todo > 32767)
  211.   {
  212.     clearStatus();
  213.     printf("OS_NETSHUTDOWN: ");
  214.     errorPrint(todo & 255);
  215.     return 255;
  216.   }
  217.   else
  218.   {
  219.     if (logFlag)
  220.     {
  221.       clearStatus();
  222.       printf("OS_NETSHUTDOWN: Socket #%u closed.", socket);
  223.     }
  224.   }
  225.   return 0;
  226. }
  227.  
  228. unsigned char netConnect(unsigned char socket)
  229. {
  230.   unsigned int todo, retry = 10;
  231.  
  232.   targetadr.family = AF_INET;
  233.   targetadr.porth = 00;
  234.   targetadr.portl = 80;
  235.   targetadr.b1 = 217;
  236.   targetadr.b2 = 146;
  237.   targetadr.b3 = 69;
  238.   targetadr.b4 = 13;
  239.   while (retry > 0)
  240.   {
  241.     todo = OS_NETCONNECT(socket, &targetadr);
  242.  
  243.     if (todo > 32767)
  244.     {
  245.       retry--;
  246.       clearStatus();
  247.       printf("OS_NETCONNECT [ERROR:");
  248.       errorPrint(todo & 255);
  249.       printf("] [Retry:%u]", retry);
  250.       YIELD();
  251.       netShutDown(socket, 0);
  252.       socket = OpenSock(AF_INET, SOCK_STREAM);
  253.     }
  254.     else
  255.     {
  256.       if (logFlag)
  257.       {
  258.         clearStatus();
  259.         printf("OS_NETCONNECT: connected , %u", (todo & 255));
  260.       }
  261.       return 1;
  262.     }
  263.   }
  264.   getchar();
  265.   exit(0);
  266.   return 0;
  267. }
  268.  
  269. unsigned int tcpRead(unsigned char socket)
  270. {
  271.   unsigned char retry = 20;
  272.   unsigned int err, todo;
  273.   readStruct.socket = socket;
  274.   readStruct.BufAdr = (unsigned int)&netbuf;
  275.   readStruct.bufsize = sizeof(netbuf);
  276.   readStruct.protocol = SOCK_STREAM;
  277.  
  278. wizread:
  279.   todo = OS_WIZNETREAD(&readStruct);
  280.   if (todo > 32767)
  281.   {
  282.     if (retry == 0)
  283.     {
  284.       err = todo & 255;
  285.       clearStatus();
  286.       printf("OS_WIZNETREAD: ");
  287.       errorPrint(err);
  288.       if (err == ERR_EAGAIN)
  289.       {
  290.         return 0;
  291.       }
  292.       exit(0);
  293.     }
  294.     retry--;
  295.     if (logFlag)
  296.     {
  297.       AT(54, 25);
  298.       printf("OS_WIZNETREAD: retry %u   ", retry);
  299.     }
  300.     delay(200);
  301.     goto wizread;
  302.   }
  303.   if (logFlag)
  304.   {
  305.     clearStatus();
  306.     printf("OS_WIZNETREAD: %u bytes read.", todo);
  307.   }
  308.   return todo;
  309. }
  310.  
  311. int pos(unsigned char *s, unsigned char *c, unsigned int n, unsigned int startPos)
  312. {
  313.   unsigned int i, j;
  314.   unsigned int lenC, lenS;
  315.  
  316.   for (lenC = 0; c[lenC]; lenC++)
  317.     ;
  318.   for (lenS = 0; s[lenS]; lenS++)
  319.     ;
  320.  
  321.   for (i = startPos; i <= lenS - lenC; i++)
  322.   {
  323.     for (j = 0; s[i + j] == c[j]; j++)
  324.       ;
  325.  
  326.     if (j - lenC == 1 && i == lenS - lenC && !(n - 1))
  327.       return i;
  328.     if (j == lenC)
  329.       if (n - 1)
  330.         n--;
  331.       else
  332.         return i;
  333.   }
  334.   return -1;
  335. }
  336.  
  337. char *str_replace(char *dst, int num, const char *str,
  338.                   const char *orig, const char *rep)
  339. {
  340.   const char *ptr;
  341.   size_t len1 = strlen(orig);
  342.   size_t len2 = strlen(rep);
  343.   char *tmp = dst;
  344.  
  345.   num -= 1;
  346.   while ((ptr = strstr(str, orig)) != NULL)
  347.   {
  348.     num -= (ptr - str) + len2;
  349.     if (num < 1)
  350.       break;
  351.  
  352.     strncpy(dst, str, (size_t)(ptr - str));
  353.     dst += ptr - str;
  354.     strncpy(dst, rep, len2);
  355.     dst += len2;
  356.     str = ptr + len1;
  357.   }
  358.  
  359.   for (; (*dst = *str) && (num > 0); --num)
  360.   {
  361.     ++dst;
  362.     ++str;
  363.   }
  364.   return tmp;
  365. }
  366.  
  367. const char *parseJson(unsigned char *property)
  368. {
  369.   unsigned int w, lng, lngp1, findEnd, listPos;
  370.   unsigned char terminator;
  371.   int n;
  372.   n = -1;
  373.   netbuf[0] = '\0';
  374.   n = pos(dataBuffer, property, 1, 0);
  375.   if (n == -1)
  376.   {
  377.     strcpy(netbuf, "0\0");
  378.     return netbuf;
  379.   }
  380.   lng = n - 1 + strlen(property);
  381.   if (dataBuffer[lng] == ':')
  382.   {
  383.     terminator = '\0';
  384.   }
  385.   if (dataBuffer[lng] == '\"')
  386.   {
  387.     terminator = '\"';
  388.   }
  389.   if (dataBuffer[lng] == '[')
  390.   {
  391.     terminator = ']';
  392.   }
  393.  
  394.   findEnd = 1;
  395.   lngp1 = lng + 1;
  396.  
  397.   while (42)
  398.   {
  399.  
  400.     if ((dataBuffer[lngp1 + findEnd] == ','))
  401.     {
  402.       if (terminator == '\0')
  403.       {
  404.         break;
  405.       }
  406.       if ((dataBuffer[lng + findEnd] == terminator))
  407.       {
  408.         findEnd--;
  409.         break;
  410.       }
  411.     }
  412.     findEnd++;
  413.   }
  414.   listPos = 0;
  415.   for (w = lngp1; w < findEnd + lngp1; w++)
  416.   {
  417.     netbuf[listPos] = dataBuffer[w];
  418.     listPos++;
  419.   }
  420.   netbuf[listPos] = '\0';
  421.   return netbuf;
  422. }
  423. void convert866(void)
  424. {
  425.   unsigned int lng, targetPos, w, q = 0;
  426.   unsigned char buffer[8], one, two;
  427.   unsigned int decVal;
  428.   lng = strlen(netbuf);
  429.   targetPos = lng + 1;
  430.  
  431.   while (q < lng)
  432.   {
  433.     one = netbuf[q];
  434.     two = netbuf[q + 1];
  435.     if (one == 92 && two == 117)
  436.     {
  437.       q = q + 2;
  438.       for (w = 0; w < 4; w++)
  439.       {
  440.         buffer[w] = netbuf[q + w];
  441.       }
  442.       q = q + 4;
  443.       buffer[4] = '\0';
  444.       decVal = (unsigned int)strtol(buffer, NULL, 16);
  445.  
  446.       if (decVal < 1088)
  447.       {
  448.         decVal = decVal - 912;
  449.       }
  450.       if (decVal > 1087)
  451.       {
  452.         decVal = decVal - 864;
  453.       }
  454.       if (decVal == 1025)
  455.       {
  456.         decVal = 240;
  457.       }
  458.       if (decVal == 1105)
  459.       {
  460.         decVal = 241;
  461.       }
  462.       netbuf[targetPos] = decVal;
  463.     }
  464.     else
  465.     {
  466.       netbuf[targetPos] = netbuf[q];
  467.       q++;
  468.     }
  469.     targetPos++;
  470.   }
  471.   netbuf[targetPos] = '\0';
  472.  
  473.   for (w = lng + 1; w < targetPos + 1; w++)
  474.   {
  475.     netbuf[w - lng - 1] = netbuf[w];
  476.   }
  477. }
  478.  
  479. unsigned int cutHeader(unsigned int todo)
  480. {
  481.   unsigned int q, headlng;
  482.   unsigned char *count;
  483.   count = strstr(netbuf, "Content-Length:");
  484.   if (count == NULL)
  485.   {
  486.     clearStatus();
  487.     printf("Content-Length:  not found.");
  488.     contLen = 0;
  489.   }
  490.   else
  491.   {
  492.     contLen = atol(count + 15);
  493.     curFileStruct.fileSize = contLen;
  494.     //  printf("=> Dlinna  soderzhimogo = %lu \n\r", curFileStruct.fileSize);
  495.   }
  496.  
  497.   count = strstr(netbuf, "\r\n\r\n");
  498.   headlng = ((unsigned int)count - (unsigned int)netbuf + 4);
  499.   q = todo - headlng;
  500.   memcpy(&netbuf, count + 4, q);
  501.   return q;
  502. }
  503.  
  504. void nameRepair(unsigned char *pfn, unsigned int tfnSize)
  505. {
  506.   str_replace(pfn, tfnSize, pfn, "\\", "_");
  507.   str_replace(pfn, tfnSize, pfn, "/", "_");
  508.   str_replace(pfn, tfnSize, pfn, ":", "_");
  509.   str_replace(pfn, tfnSize, pfn, "*", "_");
  510.   str_replace(pfn, tfnSize, pfn, "?", "_");
  511.   str_replace(pfn, tfnSize, pfn, "<", "_");
  512.   str_replace(pfn, tfnSize, pfn, ">", "_");
  513.   str_replace(pfn, tfnSize, pfn, "|", "_");
  514.   str_replace(pfn, tfnSize, pfn, " ", "_");
  515.   str_replace(pfn, tfnSize, pfn, "&#039;", "'");
  516.   str_replace(pfn, tfnSize, pfn, "&amp;", "&");
  517.   str_replace(pfn, tfnSize, pfn, "&quot;", "'");
  518.   str_replace(pfn, tfnSize, pfn, "&gt;", ")");
  519.   str_replace(pfn, tfnSize, pfn, "&lt;", "(");
  520.   str_replace(pfn, tfnSize, pfn, "\"", "'");
  521. }
  522.  
  523. void stringRepair(unsigned char *pfn, unsigned int tSize)
  524. {
  525.   str_replace(pfn, tSize, pfn, "&#039;", "'");
  526.   str_replace(pfn, tSize, pfn, "&amp;", "&");
  527.   str_replace(pfn, tSize, pfn, "&gt;", ">");
  528.   str_replace(pfn, tSize, pfn, "&lt;", "<");
  529.   str_replace(pfn, tSize, pfn, "&quot;", "\"");
  530.   str_replace(pfn, tSize, pfn, "\\/", "/");
  531. }
  532.  
  533. void ncReplace(void)
  534. {
  535.   unsigned char len;
  536.   for (len = 0; len < strlen(curFileStruct.afn); len++)
  537.   {
  538.     if (curFileStruct.afn[len] < ' ')
  539.     {
  540.       curFileStruct.afn[len] = '_';
  541.     }
  542.   }
  543.  
  544.   for (len = 0; len < strlen(curFileStruct.tfn); len++)
  545.   {
  546.     if (curFileStruct.tfn[len] < ' ')
  547.     {
  548.       curFileStruct.tfn[len] = '_';
  549.     }
  550.   }
  551. }
  552.  
  553. unsigned char saveBuf(unsigned long fileId, unsigned char operation, unsigned int sizeOfBuf)
  554. {
  555.   FILE *fp2;
  556.   unsigned long fileSize;
  557.   unsigned char afnSize, tfnSize;
  558.   unsigned char fileIdChar[10];
  559.  
  560.   if (operation == 00)
  561.   {
  562.  
  563.     if (saveFlag == 0)
  564.     {
  565.       sprintf(curFileStruct.fileName, "temp.%s", formats[curFormat]);
  566.     }
  567.     else
  568.     {
  569.       afnSize = sizeof(curFileStruct.afn) - 1;
  570.       tfnSize = sizeof(curFileStruct.tfn) - 1;
  571.  
  572.       strcpy(curFileStruct.afn, curFileStruct.authorTitle);
  573.       nameRepair(curFileStruct.afn, afnSize);
  574.       strcpy(curFileStruct.tfn, curFileStruct.trackName);
  575.       nameRepair(curFileStruct.tfn, tfnSize);
  576.       sprintf(curFileStruct.fileName, "%s-%s.%s", curFileStruct.afn, curFileStruct.tfn, formats[curFormat]);
  577.       ncReplace();
  578.  
  579.       if (strlen(curFileStruct.fileName) > 63)
  580.       {
  581.         sprintf(fileIdChar, "-%ld", fileId);
  582.         str_replace(curFileStruct.fileName, sizeof(curFileStruct.fileName) - 1, curFileStruct.fileName, fileIdChar, "");
  583.         curFileStruct.fileName[50] = '\0';
  584.         strcat(curFileStruct.fileName, fileIdChar);
  585.         strcat(curFileStruct.fileName, formats[curFormat]);
  586.       }
  587.     }
  588.     OS_SETSYSDRV();
  589.     OS_MKDIR("../downloads/radio"); // Create if not exist
  590.     OS_CHDIR("../downloads/radio");
  591.     fp2 = OS_CREATEHANDLE(curFileStruct.fileName, 0x80);
  592.     if (((int)fp2) & 0xff)
  593.     {
  594.       clearStatus();
  595.       printf(curFileStruct.fileName);
  596.       printf(" creating error. Check for  downloads\\radio folder.");
  597.       getchar();
  598.       exit(0);
  599.     }
  600.     OS_CLOSEHANDLE(fp2);
  601.     return 0;
  602.   }
  603.  
  604.   if (operation == 01)
  605.   {
  606.     fp2 = OS_OPENHANDLE(curFileStruct.fileName, 0x80);
  607.     if (((int)fp2) & 0xff)
  608.     {
  609.  
  610.       clearStatus();
  611.       printf(curFileStruct.fileName);
  612.       printf(" opening error.");
  613.       exit(0);
  614.     }
  615.     fileSize = OS_GETFILESIZE(fp2);
  616.     OS_SEEKHANDLE(fp2, fileSize);
  617.     OS_WRITEHANDLE(netbuf, fp2, sizeOfBuf);
  618.     OS_CLOSEHANDLE(fp2);
  619.     return 0;
  620.   }
  621.  
  622.   if (operation == 02)
  623.   {
  624.     OS_CLOSEHANDLE(fp2);
  625.     return 0;
  626.   }
  627.  
  628.   return 0;
  629. }
  630.  
  631. void getData(unsigned char socket)
  632. {
  633.   unsigned int todo, w, bPos, headskip;
  634.  
  635.   headskip = 0;
  636.   bPos = 0;
  637.   while (1)
  638.   {
  639.     todo = tcpRead(socket);
  640.     if (todo == 0)
  641.     {
  642.       break;
  643.     }
  644.     if (headskip == 0)
  645.     {
  646.       headskip = 1;
  647.       todo = cutHeader(todo);
  648.     }
  649.  
  650.     if (bPos + todo > sizeof(dataBuffer))
  651.     {
  652.       clearStatus();
  653.       printf("dataBuffer overrun...");
  654.       break;
  655.     }
  656.  
  657.     for (w = 0; w < todo; w++)
  658.     {
  659.       dataBuffer[w + bPos] = netbuf[w];
  660.     }
  661.     bPos = bPos + todo;
  662.     if (bPos == contLen)
  663.     {
  664.       // dataBuffer[todo + bPos + 1] = '\0';
  665.       break;
  666.     }
  667.   }
  668.   netShutDown(socket, 1);
  669. }
  670.  
  671. unsigned int tcpSend(unsigned char socket, unsigned int messageadr, unsigned int size)
  672. {
  673.   unsigned char retry = 20;
  674.   unsigned int todo;
  675.   readStruct.socket = socket;
  676.   readStruct.BufAdr = messageadr;
  677.   readStruct.bufsize = size;
  678.   readStruct.protocol = SOCK_STREAM;
  679.  
  680. wizwrite:
  681.   todo = OS_WIZNETWRITE(&readStruct);
  682.   if (todo > 32767)
  683.   {
  684.     clearStatus();
  685.     printf("OS_WIZNETWRITE: ");
  686.     errorPrint(todo & 255);
  687.     if (retry == 0)
  688.     {
  689.       exit(0);
  690.     }
  691.     retry--;
  692.     delay(150);
  693.     goto wizwrite;
  694.   }
  695.   else
  696.   {
  697.     if (logFlag)
  698.     {
  699.       clearStatus();
  700.       printf("OS_WIZNETWRITE: %u bytes written.", todo);
  701.     }
  702.   }
  703.   return todo;
  704. }
  705.  
  706. unsigned long processJson(unsigned long startPos, unsigned char limit, unsigned char queryNum)
  707. {
  708.   FILE *fp3;
  709.   unsigned int retry, tSize;
  710.   unsigned int todo;
  711.   unsigned char buffer[] = "000000000";
  712.   unsigned char *count, socket;
  713.   unsigned char userAgent[] = " HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS; Radio)\r\n\r\n\0";
  714.   unsigned char userQuery[256] = "/api/export:zxMusic/limit:10/filter:zxMusicId=44816";
  715.   clearStatus();
  716.   printf("Getting data(%u)...", queryNum);
  717.  
  718.   switch (queryNum)
  719.   {
  720.   case 0: // GET /api/export:zxMusic/limit:1/start:1/filter:zxMusicFormat=pt3/order:date,desc HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)
  721.     strcpy(netbuf, "GET /api/export:zxMusic/limit:");
  722.     sprintf(buffer, "%u", limit);
  723.     strcat(netbuf, buffer);
  724.     strcat(netbuf, "/start:");
  725.     sprintf(buffer, "%lu", startPos);
  726.     strcat(netbuf, buffer);
  727.     strcat(netbuf, "/filter:zxMusicFormat=");
  728.     strcat(netbuf, formats[curFormat]);
  729.     strcat(netbuf, "/order:date,desc");
  730.     strcat(netbuf, userAgent);
  731.     break;
  732.   case 1: // GET /api/types:zxMusic/export:zxMusic/language:eng/limit:1/start:0/order:votes,rand/filter:zxMusicMinRating=4;
  733.     startPos = 0;
  734.     strcpy(netbuf, "GET /api/types:zxMusic/export:zxMusic/language:eng/limit:");
  735.     sprintf(buffer, "%u", limit);
  736.     strcat(netbuf, buffer);
  737.     strcat(netbuf, "/start:");
  738.     sprintf(buffer, "%lu", startPos);
  739.     strcat(netbuf, buffer);
  740.     strcat(netbuf, "/order:votes,rand/filter:zxMusicMinRating=4;zxMusicFormat=");
  741.     strcat(netbuf, formats[curFormat]);
  742.     strcat(netbuf, userAgent);
  743.     break;
  744.   case 2: // GET /api/types:zxMusic/export:zxMusic/language:eng/limit:1/start:0/order:rand/filter:zxMusicFormat=PT3 HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)
  745.     startPos = 0;
  746.     strcpy(netbuf, "GET /api/types:zxMusic/export:zxMusic/language:eng/limit:");
  747.     sprintf(buffer, "%u", limit);
  748.     strcat(netbuf, buffer);
  749.     strcat(netbuf, "/start:");
  750.     sprintf(buffer, "%lu", startPos);
  751.     strcat(netbuf, buffer);
  752.     strcat(netbuf, "/order:rand/filter:zxMusicFormat=");
  753.     strcat(netbuf, formats[curFormat]);
  754.     strcat(netbuf, userAgent);
  755.     break;
  756.  
  757.   case 3: // GET /api/export:zxMusic/limit:1/start:1/filter:zxMusicFormat=pt3;authorId=7744/order:date,desc HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS)
  758.  
  759.     fp3 = OS_OPENHANDLE("radio/user.que", 0x80);
  760.     if (((int)fp3) & 0xff)
  761.     {
  762.       fp3 = OS_CREATEHANDLE("radio/user.que", 0x80);
  763.       OS_WRITEHANDLE(userQuery, fp3, sizeof(userQuery));
  764.       OS_CLOSEHANDLE(fp3);
  765.       fp3 = OS_OPENHANDLE("radio/user.que", 0x80);
  766.     }
  767.     OS_READHANDLE(userQuery, fp3, sizeof(userQuery));
  768.     OS_CLOSEHANDLE(fp3);
  769.  
  770.     strcpy(netbuf, "GET /api/limit:");
  771.     sprintf(buffer, "%u", limit);
  772.     strcat(netbuf, buffer);
  773.     strcat(netbuf, "/start:");
  774.     sprintf(buffer, "%lu", startPos);
  775.     strcat(netbuf, buffer);
  776.     strcat(netbuf, userQuery);
  777.     strcat(netbuf, userAgent);
  778.     break;
  779.  
  780.   case 99: // GET /jsonElementData/elementId:182798
  781.     strcpy(netbuf, "GET /jsonElementData/elementId:");
  782.     sprintf(buffer, "%lu", startPos);
  783.     strcat(netbuf, buffer);
  784.     strcat(netbuf, userAgent);
  785.     break;
  786.   }
  787.  
  788.   retry = 10;
  789. rejson:
  790.   socket = OpenSock(AF_INET, SOCK_STREAM);
  791.   netConnect(socket);
  792.  
  793.   todo = tcpSend(socket, (unsigned int)&netbuf, strlen(netbuf));
  794.  
  795.   getData(socket);
  796.  
  797.   clearStatus();
  798.   printf("Processing data (%u)...", queryNum);
  799.  
  800.   count = strstr(dataBuffer, "responseStatus\":\"success");
  801.   if (count == NULL)
  802.   {
  803.     clearStatus();
  804.     printf("BAD JSON, NO responseStatus: success. (%u)", retry);
  805.     retry--;
  806.     YIELD();
  807.     if (retry > 0)
  808.     {
  809.       netShutDown(socket, 1);
  810.       goto rejson;
  811.     }
  812.     return -1;
  813.   }
  814.  
  815.   count = strstr(dataBuffer, "\"id\":");
  816.   if (count == NULL)
  817.   {
  818.     clearStatus();
  819.     printf("BAD JSON: not ID query = %u startPos = %lu", queryNum, startPos);
  820.     return -2;
  821.   }
  822.   if (queryNum < 4)
  823.   {
  824.     netbuf[0] = '\0';
  825.     parseJson("\"id\":");
  826.     curFileStruct.picId = atol(netbuf);
  827.     parseJson(",\"title\":\"");
  828.     convert866();
  829.     strcpy(curFileStruct.trackName, netbuf);
  830.  
  831.     tSize = sizeof(curFileStruct.trackName);
  832.     stringRepair(curFileStruct.trackName, tSize);
  833.  
  834.     parseJson("\"rating\":\"");
  835.     strcpy(curFileStruct.picRating, netbuf);
  836.     parseJson("\"year\":\"");
  837.     curFileStruct.picYear = atoi(netbuf);
  838.     parseJson("\"totalAmount\":");
  839.     curFileStruct.totalAmount = atol(netbuf);
  840.     parseJson("\"time\":\"");
  841.     strcpy(curFileStruct.time, netbuf);
  842.     parseJson("\"authorIds\":[");
  843.     strcpy(curFileStruct.authorIds, netbuf);
  844.     parseJson("\"authorIds\":[");
  845.     strcpy(curFileStruct.fileName2, netbuf);
  846.   }
  847.   if (queryNum == 99)
  848.   {
  849.     parseJson(",\"title\":\"");
  850.     convert866();
  851.     strcpy(curFileStruct.authorTitle, netbuf);
  852.     parseJson(",\"realName\":\"");
  853.     convert866();
  854.     strcpy(curFileStruct.authorRealName, netbuf);
  855.   }
  856.   return curFileStruct.picId;
  857. }
  858.  
  859. unsigned char getTrack(unsigned long fileId)
  860. {
  861.   unsigned int todo;
  862.   unsigned char cmdlist1[] = "GET /file/id:";
  863.   unsigned char cmdlist2[] = " HTTP/1.1\r\nHost: zxart.ee\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE5.01; NedoOS; Radio)\r\n\r\n\0";
  864.   unsigned char buffer[] = "0000000000";
  865.   unsigned char socket;
  866.   unsigned int headskip;
  867.   unsigned long bytecount;
  868.   clearStatus();
  869.   printf("Getting track...");
  870.  
  871.   socket = OpenSock(AF_INET, SOCK_STREAM);
  872.   todo = netConnect(socket);
  873.   sprintf(buffer, "%lu", fileId);
  874.   strcpy(netbuf, cmdlist1);
  875.   strcat(netbuf, buffer);
  876.   strcat(netbuf, cmdlist2);
  877.   todo = tcpSend(socket, (unsigned int)&netbuf, strlen(netbuf));
  878.  
  879.   headskip = 0;
  880.   bytecount = 255;
  881.   saveBuf(curFileStruct.picId, 00, 0);
  882.   while (bytecount != 0)
  883.   {
  884.     todo = tcpRead(socket);
  885.     if (todo == 0)
  886.     {
  887.       break;
  888.     }
  889.     if (headskip == 0)
  890.     {
  891.       headskip = 1;
  892.       todo = cutHeader(todo);
  893.       bytecount = contLen;
  894.     }
  895.     saveBuf(curFileStruct.picId, 01, todo);
  896.     bytecount = bytecount - todo;
  897.   }
  898.   netShutDown(socket, 0);
  899.   return 0;
  900. }
  901.  
  902. unsigned char runPlayer(void)
  903. {
  904.   FILE *fp2;
  905.   unsigned char fileName[] = "radio/player.ovl";
  906.   unsigned char appCmd[128] = "player.com ";
  907.   unsigned char curPath[128];
  908.   unsigned long playerSize, loaded, loop;
  909.   unsigned char pgbak;
  910.  
  911.   clearStatus();
  912.   printf("Running player...");
  913.  
  914.   strcat(appCmd, curFileStruct.fileName);
  915.   player_pg.l = OS_GETMAINPAGES();
  916.   pgbak = main_pg.pgs.window_3;
  917.   loaded = 0;
  918.   OS_GETPATH((unsigned int)&curPath);
  919.   OS_SETSYSDRV();
  920.   fp2 = OS_OPENHANDLE(fileName, 0x80);
  921.   if (((int)fp2) & 0xff)
  922.   {
  923.     clearStatus();
  924.     printf("%s", fileName);
  925.     printf(" not found.");
  926.     exit(0);
  927.   }
  928.   playerSize = OS_GETFILESIZE(fp2);
  929.   OS_CHDIR(curPath);
  930.   OS_NEWAPP((unsigned int)&player_pg);
  931.   SETPG32KHIGH(player_pg.pgs.window_3);
  932.   memcpy((char *)(0xC080), &appCmd, sizeof(appCmd));
  933.   for (loop = 0; loop < playerSize; loop = loop + loaded)
  934.   {
  935.     loaded = OS_READHANDLE(dataBuffer, fp2, sizeof(dataBuffer));
  936.     memcpy((char *)(0xC100 + loop), &dataBuffer, loaded);
  937.   }
  938.   OS_CLOSEHANDLE(fp2);
  939.   SETPG32KHIGH(pgbak);
  940.   OS_RUNAPP(player_pg.pgs.pId);
  941.   return player_pg.pgs.pId;
  942. }
  943.  
  944. long trackSelector(unsigned char mode)
  945. {
  946.   switch (mode)
  947.   {
  948.   case 0: // Next track
  949.     count++;
  950.     if (count > curFileStruct.totalAmount - 1)
  951.     {
  952.       count = 0;
  953.     }
  954.     break;
  955.   case 1: // Prev. track
  956.     count--;
  957.     if (count < 0)
  958.     {
  959.       count = curFileStruct.totalAmount - 1;
  960.     }
  961.     break;
  962.   }
  963.   return count;
  964. }
  965.  
  966. void printStatus(void)
  967. {
  968.   AT(1, 9);
  969.   ATRIB(93);
  970.   printf(" [Q]Query : ");
  971.   ATRIB(97);
  972.   printf("%s", queryType);
  973.   printf("  ");
  974.   AT(1, 24);
  975.   ATRIB(45);
  976.   printf("                                                                                ");
  977.   AT(2, 24);
  978.   ATRIB(93);
  979.   printf(" [F]Format: ");
  980.   ATRIB(97);
  981.   printf("%s", formats[curFormat]);
  982.   ATRIB(93);
  983.   printf(" [K]Keep files: ");
  984.   ATRIB(97);
  985.   printf("%u", saveFlag);
  986.   ATRIB(93);
  987.   printf(" [R]Repeat: ");
  988.   ATRIB(97);
  989.   printf("%u", rptFlag);
  990.   ATRIB(93);
  991.   printf(" [J]Jump to ");
  992.   printf(" [E]Exit        [%s]\r\n", ver);
  993.  
  994.   ATRIB(97);
  995.   ATRIB(40);
  996. }
  997.  
  998. void printInfo(void)
  999. {
  1000.   BOX(30, 2, 50, 6, 40);
  1001.   AT(1, 2);
  1002.   ATRIB(97);
  1003.   ATRIB(93);
  1004.   printf(" #: ");
  1005.   ATRIB(97);
  1006.   printf("%lu", count);
  1007.   ATRIB(93);
  1008.   printf(" ID: ");
  1009.   ATRIB(97);
  1010.   printf("%lu", curFileStruct.picId);
  1011.   ATRIB(93);
  1012.   printf(" Total Tracks: ");
  1013.   ATRIB(97);
  1014.   printf("%lu", curFileStruct.totalAmount);
  1015.   printf(" \r\n");
  1016.   ATRIB(93);
  1017.   printf(" RATING: ");
  1018.   ATRIB(97);
  1019.   printf("%s", curFileStruct.picRating);
  1020.   ATRIB(93);
  1021.   printf(" YEAR: ");
  1022.   ATRIB(97);
  1023.   printf("%u", curFileStruct.picYear);
  1024.   ATRIB(93);
  1025.   printf(" DURATION: ");
  1026.   ATRIB(97);
  1027.   printf("%s", curFileStruct.time);
  1028.   printf(" \r\n\r\n");
  1029.   ATRIB(93);
  1030.   printf(" AuthorsIDs ");
  1031.   ATRIB(97);
  1032.   printf("%s", curFileStruct.authorIds);
  1033.   ATRIB(93);
  1034.   printf(" Author: ");
  1035.   ATRIB(97);
  1036.   printf("%s", curFileStruct.authorTitle);
  1037.   ATRIB(93);
  1038.   printf(" Real name: ");
  1039.   ATRIB(97);
  1040.   printf("%s", curFileStruct.authorRealName);
  1041.   printf(" \r\n\r\n");
  1042.   ATRIB(96);
  1043.   printf("                                                                           \r");
  1044.   printf("   TITLE: %s\r\n", curFileStruct.trackName);
  1045. }
  1046.  
  1047. void printHelp(void)
  1048. {
  1049.   AT(1, 13);
  1050.   ATRIB(97);
  1051.   printf(" [E] or [ESC] Exit to OS           \r\n");
  1052.   printf(" [B] or [<--] Previous track       \r\n");
  1053.   printf(" [ ] or [-->] Next track    \r\n");
  1054.   printf(" [S]          Stop player          \r\n");
  1055.   printf(" [K]          Toggle saving tracks \r\n");
  1056.   printf(" [Q]          Select Query type    \r\n");
  1057.   printf(" [D]          Download track       \r\n");
  1058.   printf(" [R]          Repeat track mode    \r\n");
  1059.   printf(" [J]          Jump to NNNN file from newest  \r\n");
  1060.   printf(" [F]          Change tracks format to play   \r\n");
  1061.   printf(" [L]          Toggle operation logging       \r\n");
  1062. }
  1063.  
  1064. unsigned char testPlayer(void)
  1065. {
  1066.   union APP_PAGES player2_pg;
  1067.   player2_pg.l = OS_GETAPPMAINPAGES(player_pg.pgs.pId);
  1068.  
  1069.   if (errno == 0)
  1070.   {
  1071.     return 1;
  1072.   }
  1073.   else
  1074.   {
  1075.     return 0;
  1076.   }
  1077. }
  1078.  
  1079. C_task main(void)
  1080. {
  1081.   unsigned char errn, keypress, queryNum, pId, alive, changedFormat;
  1082.   long iddqd, idkfa, ipadress;
  1083.   unsigned long curTimer, startTimer, oldTimer;
  1084.   os_initstdio();
  1085.   srand(time());
  1086.   count = 0;
  1087.   saveFlag = 0;
  1088.   logFlag = 0;
  1089.   queryNum = 0;
  1090.   curFormat = 0;
  1091.   changedFormat = 0;
  1092.   rptFlag = 0;
  1093.   strcpy(queryType, "from newest to oldest");
  1094.  
  1095.   BOX(1, 1, 80, 25, 40);
  1096.   AT(1, 1);
  1097.   ATRIB(97);
  1098.   ATRIB(45);
  1099.   printf("                           ZXART.EE radio for nedoNET                           \n\r");
  1100.   AT(1, 24);
  1101.   printf("  [L]Enable logging(press on startup)                                          ");
  1102.  
  1103.   ATRIB(33);
  1104.   ATRIB(40);
  1105.  
  1106.   /*
  1107.     ipadress = OS_DNSRESOLVE("zxart.ee");
  1108.     printf("\n\r  OS_DNSRESOLVE =  %lu \n\r", ipadress);
  1109.     printf("------------------------\n\r");
  1110.     printf("OS_GETPATH = %s\r\n", curPath);
  1111.   */
  1112.  
  1113.   keypress = _low_level_get();
  1114.   if (keypress == 'l' || keypress == 'L')
  1115.   {
  1116.     logFlag = 1;
  1117.     clearStatus();
  1118.     printf("Logging enabled");
  1119.     getchar();
  1120.   }
  1121.  
  1122. start:
  1123.   OS_SETSYSDRV();
  1124.   printHelp();
  1125.   curFileStruct.fileSize = 0;
  1126.  
  1127.   iddqd = processJson(count, 1, queryNum); // Query for track info
  1128.   if (iddqd < 0)
  1129.   {
  1130.     {
  1131.       clearStatus();
  1132.       printf("Error getting track info, next please(%ld)...", iddqd);
  1133.       count = trackSelector(0);
  1134.       goto start;
  1135.     }
  1136.   }
  1137.  
  1138.   idkfa = processJson(atol(curFileStruct.authorIds), 0, 99); // Query for AuthorID
  1139.  
  1140.   if (idkfa < 0)
  1141.   {
  1142.     clearStatus();
  1143.     printf("Error getting author %lu", atol(curFileStruct.authorIds));
  1144.     strcpy(curFileStruct.authorTitle, " Error getting Tittle ");
  1145.     // strcpy(curFileStruct.authorRealName, " \0");
  1146.   }
  1147. replay:
  1148.   errn = getTrack(iddqd); // Downloading the track
  1149. resume:
  1150.   startTimer = time();
  1151.   printProgress(0);
  1152.   pId = runPlayer(); // Start thr Player!
  1153.   printStatus();
  1154.   printInfo();
  1155. rekey:
  1156.   YIELD();
  1157.   keypress = _low_level_get();
  1158.   if (keypress != 0)
  1159.   {
  1160.     if (keypress == 27 || keypress == 'e' || keypress == 'E')
  1161.     {
  1162.       OS_DROPAPP(pId);
  1163.       BOX(1, 1, 80, 25, 40);
  1164.       AT(1, 1);
  1165.       printf("Good bye...\r\n");
  1166.       ATRIB(37);
  1167.       ATRIB(40);
  1168.       exit(0);
  1169.     }
  1170.     if (keypress == 248 || keypress == 'b' || keypress == 'B')
  1171.     {
  1172.       changedFormat = 0;
  1173.       OS_DROPAPP(pId);
  1174.       clearStatus();
  1175.       printf("Player stopped...");
  1176.       count = trackSelector(1);
  1177.       goto start;
  1178.     }
  1179.  
  1180.     if (keypress == 251 || keypress == 32 || keypress == 'n' || keypress == 'N')
  1181.     {
  1182.       changedFormat = 0;
  1183.       OS_DROPAPP(pId);
  1184.       clearStatus();
  1185.       printf("Player stopped...");
  1186.       count = trackSelector(0);
  1187.       goto start;
  1188.     }
  1189.  
  1190.     if (keypress == 'k' || keypress == 'K')
  1191.     {
  1192.       OS_DROPAPP(pId);
  1193.       clearStatus();
  1194.       printf("Player stopped...");
  1195.       saveFlag = !saveFlag;
  1196.       printStatus();
  1197.       goto replay;
  1198.     }
  1199.  
  1200.     if (keypress == 'q' || keypress == 'Q')
  1201.     {
  1202.       OS_DROPAPP(pId);
  1203.       clearStatus();
  1204.       printf("Player stopped...");
  1205.       queryNum++;
  1206.       if (queryNum > 3)
  1207.       {
  1208.         queryNum = 0;
  1209.       }
  1210.       switch (queryNum)
  1211.       {
  1212.       case 0:
  1213.         strcpy(queryType, "from newest to oldest                   ");
  1214.         break;
  1215.       case 1:
  1216.         strcpy(queryType, "Random best and most voted tracks       ");
  1217.         break;
  1218.       case 2:
  1219.         strcpy(queryType, "Random play                             ");
  1220.         break;
  1221.       case 3:
  1222.         strcpy(queryType, "User defined query from \"user.que\"     ");
  1223.         break;
  1224.       }
  1225.       count = 0;
  1226.       printStatus();
  1227.       goto start;
  1228.     }
  1229.  
  1230.     if (keypress == 'j' || keypress == 'J')
  1231.     {
  1232.       AT(1, 7);
  1233.       printf("                                                                      \r");
  1234.       printf("Jump to track:");
  1235.       scanf("%lu", &count);
  1236.       OS_DROPAPP(pId);
  1237.       if (count > curFileStruct.totalAmount - 1)
  1238.       {
  1239.         count = curFileStruct.totalAmount - 1;
  1240.       }
  1241.       goto start;
  1242.     }
  1243.  
  1244.     if (keypress == 'f' || keypress == 'F')
  1245.     {
  1246.       OS_DROPAPP(pId);
  1247.       clearStatus();
  1248.       printf("Player stopped...");
  1249.       curFormat++;
  1250.       count = -1;
  1251.       if (curFormat > 3)
  1252.       {
  1253.         curFormat = 0;
  1254.       }
  1255.       changedFormat = 1;
  1256.       curFileStruct.totalAmount = 1;
  1257.       printStatus();
  1258.       printProgress(0);
  1259.       BOX(1, 2, 80, 6, 40);
  1260.       goto rekey;
  1261.     }
  1262.  
  1263.     if (keypress == 'l' || keypress == 'L')
  1264.     {
  1265.       logFlag = !logFlag;
  1266.       clearStatus();
  1267.       printf("Logging: %u", logFlag);
  1268.     }
  1269.  
  1270.     if (keypress == 's' || keypress == 'S')
  1271.     {
  1272.       OS_DROPAPP(pId);
  1273.       clearStatus();
  1274.       printf("Player stopped...");
  1275.       printProgress(0);
  1276.       getchar();
  1277.       goto resume;
  1278.     }
  1279.     if (keypress == 'r' || keypress == 'R')
  1280.     {
  1281.       rptFlag = !rptFlag;
  1282.       clearStatus();
  1283.       printStatus();
  1284.       goto rekey;
  1285.     }
  1286.     if (keypress == 'd' || keypress == 'D')
  1287.     {
  1288.       saveBak = saveFlag;
  1289.       saveFlag = 1;
  1290.       errn = getTrack(iddqd); // Downloading the track
  1291.       saveFlag = saveBak;
  1292.       clearStatus();
  1293.       printf("File saved: [%s]...", curFileStruct.fileName);
  1294.       goto rekey;
  1295.     }
  1296.   }
  1297.  
  1298.   curTimer = time();
  1299.   curFileStruct.curPos = (curTimer - startTimer) / 50;
  1300.   alive = testPlayer();
  1301.  
  1302.   if (alive == 0 && !changedFormat)
  1303.   {
  1304.     if (rptFlag == 1)
  1305.     {
  1306.       goto resume;
  1307.     }
  1308.     printProgress(2);
  1309.     count = trackSelector(0);
  1310.     goto start;
  1311.   }
  1312.  
  1313.   if (alive == 1 && ((curTimer - oldTimer) > 49))
  1314.   {
  1315.     printProgress(1);
  1316.     oldTimer = curTimer;
  1317.   }
  1318.  
  1319.   YIELD();
  1320.   goto rekey;
  1321. }
  1322.