Changeset 5442


Ignore:
Timestamp:
Nov 11, 2010 1:43:12 PM (4 years ago)
Author:
tboeckel
Message:
  • UpdateCheck.c, Threads.c, tcp/http.c: put the HTTP URL download into a thread. Thus the update check can now be done asynchronously as well. All in all this makes stuff like automatic and asynchronous user image download from service providers like www.gravatar.com possible.
Location:
trunk
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/ChangeLog

    r5441 r5442  
    55$Id$ 
    66$URL$ 
     7 
     82010-11-11 Thore Böckelmann <tboeckel@gmx.de> 
     9 
     10  * UpdateCheck.c, Threads.c, tcp/http.c: put the HTTP URL download into a 
     11    thread. Thus the update check can now be done asynchronously as well. All 
     12    in all this makes stuff like automatic and asynchronous user image download 
     13    from service providers like www.gravatar.com possible. 
    714 
    8152010-11-09 Thore Böckelmann <tboeckel@gmx.de> 
  • trunk/src/Threads.c

    r5439 r5442  
    6969#include "Threads.h" 
    7070 
     71#include "mui/ClassesExtra.h" 
     72#include "tcp/http.h" 
    7173#include "tcp/pop3.h" 
    7274#include "tcp/smtp.h" 
     
    108110  struct ThreadNode *threadNode;  // link to the thread's node 
    109111  struct Thread *thread;          // link to the thread itself 
     112  Object *object;                 // an object for which MUIM_ThreadFinished will be called 
    110113}; 
    111114 
     
    261264                           (struct MailList *)GetTagData(TT_ExportMails_Mails, (IPTR)NULL, msg->actionTags), 
    262265                           GetTagData(TT_ExportMails_Flags, 0, msg->actionTags)); 
     266    } 
     267    break; 
     268 
     269    case TA_DownloadURL: 
     270    { 
     271      result = DownloadURL((const char *)GetTagData(TT_DownloadURL_Server, (IPTR)NULL, msg->actionTags), 
     272                           (const char *)GetTagData(TT_DownloadURL_Request, (IPTR)NULL, msg->actionTags), 
     273                           (const char *)GetTagData(TT_DownloadURL_Filename, (IPTR)NULL, msg->actionTags), 
     274                           GetTagData(TT_DownloadURL_Flags, 0, msg->actionTags)); 
    263275    } 
    264276    break; 
     
    683695    struct ThreadMessage *tmsg = (struct ThreadMessage *)msg; 
    684696 
    685     D(DBF_THREAD, "thread '%s' finished action %ld with result %ld", tmsg->thread->name, tmsg->action, tmsg->result); 
     697    D(DBF_THREAD, "thread '%s' finished action %ld, result %ld", tmsg->thread->name, tmsg->action, tmsg->result); 
     698 
     699    if(tmsg->object != NULL) 
     700    { 
     701      D(DBF_THREAD, "sending MUIM_ThreadFinished to object %08lx", tmsg->object); 
     702      PushMethodOnStackWait(tmsg->object, 4, MUIM_ThreadFinished, tmsg->action, tmsg->result, tmsg->actionTags); 
     703    } 
    686704 
    687705    // remove the thread from the working list and put it back into the idle list 
     
    735753/// DoAction 
    736754// 
    737 BOOL VARARGS68K DoAction(const enum ThreadAction action, ...) 
     755BOOL VARARGS68K DoAction(Object *obj, const enum ThreadAction action, ...) 
    738756{ 
    739757  BOOL success = FALSE; 
     
    777795        msg->threadNode = threadNode; 
    778796        msg->thread = thread; 
     797        msg->object = obj; 
    779798 
    780799        // raise the thread's priority if this is requested 
  • trunk/src/Threads.h

    r5439 r5442  
    4444  TA_ImportMails, 
    4545  TA_ExportMails, 
     46  TA_DownloadURL, 
    4647}; 
    4748 
    48 #define TT_Priority                                 0xf001 // priority of the thread 
     49#define TT_Priority                                0xf001 // priority of the thread 
    4950 
    5051#define TT_LaunchCommand_Command     (TAG_STRING | (TAG_USER + 1)) 
     
    6768#define TT_ExportMails_Flags                       (TAG_USER + 3) 
    6869 
     70#define TT_DownloadURL_Server        (TAG_STRING | (TAG_USER + 1)) 
     71#define TT_DownloadURL_Request       (TAG_STRING | (TAG_USER + 2)) 
     72#define TT_DownloadURL_Filename      (TAG_STRING | (TAG_USER + 3)) 
     73#define TT_DownloadURL_Flags                       (TAG_USER + 4) 
     74 
    6975/*** Thread system init/cleanup functions ***/ 
    7076BOOL InitThreads(void); 
     
    7379void AbortWorkingThreads(void); 
    7480void PurgeIdleThreads(const BOOL purgeAll); 
    75 BOOL VARARGS68K DoAction(const enum ThreadAction action, ...); 
     81BOOL VARARGS68K DoAction(Object *obj, const enum ThreadAction action, ...); 
    7682BOOL IsMainThread(void); 
    7783APTR CurrentThread(void); 
  • trunk/src/Timer.c

    r5441 r5442  
    569569      D(DBF_TIMER, "timer[%ld]: TIMER_SPAMFLUSHTRAININGDATA fired @ %s", tid, dateString); 
    570570 
    571       DoAction(TA_FlushSpamTrainingData, TAG_DONE); 
     571      DoAction(NULL, TA_FlushSpamTrainingData, TAG_DONE); 
    572572 
    573573      PrepareTimer(tid, C->SpamFlushTrainingDataInterval, 0); 
  • trunk/src/UpdateCheck.c

    r5441 r5442  
    5858#include "YAM_utilities.h" 
    5959 
    60 #include "mui/ClassesExtra.h" 
    61 #include "mui/UpdateNotifyWindow.h" 
    62 #include "mime/rfc1738.h" 
    63 #include "tcp/http.h" 
    64  
    6560#include "Locale.h" 
    6661#include "MUIObjects.h" 
     
    6863#include "UpdateCheck.h" 
    6964 
    70 #include "tcp/Connection.h" 
     65#include "mui/UpdateNotifyWindow.h" 
     66#include "mime/rfc1738.h" 
    7167 
    7268#include "Debug.h" 
     
    134130// contacts the 'update.yam.ch' HTTP server and asks for 
    135131// specific updates. 
    136 BOOL CheckForUpdates(const BOOL quiet) 
    137 { 
    138   BOOL result = FALSE; 
    139   struct Connection *conn; 
    140  
     132void CheckForUpdates(const BOOL quiet) 
     133{ 
    141134  ENTER(); 
    142135 
     
    144137  LastUpdateState.LastUpdateStatus = UST_NOQUERY; 
    145138 
    146   // first we check if we can start a connection or if the 
    147   // tcp/ip stuff is busy right now so that we do not interrupt something 
    148   if((conn = CreateConnection()) != NULL) 
    149   { 
    150     // disable the transfer buttons in the toolbar 
    151     MA_ChangeTransfer(FALSE); 
    152  
    153     // pause the mail check timer so that we are not 
    154     // interfering with an automatic mail check action 
    155     PauseTimer(TIMER_CHECKMAIL); 
    156  
    157     // now we open a new TCP/IP connection socket 
    158     if(ConnectionIsOnline(conn) == TRUE) 
    159     { 
    160       struct TempFile *tf; 
    161  
    162       if((tf = OpenTempFile(NULL)) != NULL) 
    163       { 
    164         char *request; 
    165  
    166         BusyText(tr(MSG_BusyGettingVerInfo), ""); 
    167  
    168         // now we prepare our request string which we send to our update server 
    169         // and will inform it about our configuration/YAM version and so on. 
    170         // use a max. request buffer of 1K. 
    171         #define REQUEST_SIZE 1024 
    172         if((request = malloc(REQUEST_SIZE)) != NULL) // don't use stack for the request 
     139  // make sure that we have created the update notification 
     140  // window in advance. If one already exists we don't create a second one 
     141  if(G->UpdateNotifyWinObject == NULL) 
     142  { 
     143    G->UpdateNotifyWinObject = UpdateNotifyWindowObject, End; 
     144  } 
     145 
     146  if(G->UpdateNotifyWinObject != NULL) 
     147  { 
     148    DoMethod(G->UpdateNotifyWinObject, MUIM_UpdateNotifyWindow_CheckForUpdates, quiet); 
     149  } 
     150 
     151  LEAVE(); 
     152} 
     153 
     154/// 
     155/// BuildUpdateRequest 
     156// build a request string to be sent to the update server 
     157char *BuildUpdateRequest(void) 
     158{ 
     159  char *request; 
     160 
     161  // now we prepare our request string which we send to our update server 
     162  // and will inform it about our configuration/YAM version and so on. 
     163  // use a max. request buffer of 1K. 
     164  #define REQUEST_SIZE 1024 
     165  if((request = malloc(REQUEST_SIZE)) != NULL) // don't use stack for the request 
     166  { 
     167    char buf[SIZE_LINE]; 
     168    Object *mccObj; 
     169    struct Library *base; 
     170    unsigned short cnt = 0; 
     171 
     172    // encode the yam version 
     173    if(urlencode(buf, yamversion, sizeof(buf)) > 0) 
     174      snprintf(request, REQUEST_SIZE, "?ver=%s", buf); 
     175 
     176    // encode the yam buildid if present 
     177    if(urlencode(buf, yambuildid, sizeof(buf)) > 0) 
     178      snprintf(request, REQUEST_SIZE, "%s&buildid=%s", request, buf); 
     179 
     180    // encode the yam builddate if present 
     181    if(urlencode(buf, yamversiondate, sizeof(buf)) > 0) 
     182      snprintf(request, REQUEST_SIZE, "%s&builddate=%s", request, buf); 
     183 
     184    // encode the language in which YAM is running 
     185    if(G->Catalog != NULL && urlencode(buf, G->Catalog->cat_Language, sizeof(buf)) > 0) 
     186      snprintf(request, REQUEST_SIZE, "%s&lang=%s%%20%d%%2E%d", request, buf, G->Catalog->cat_Version, 
     187                                                                              G->Catalog->cat_Revision); 
     188 
     189    // Now we add some third party components 
     190    // information for our update server as well. 
     191 
     192    // encode the exec version 
     193    snprintf(request, REQUEST_SIZE, "%s&exec=%d%%2E%d", request, ((struct Library *)SysBase)->lib_Version, 
     194                                                                 ((struct Library *)SysBase)->lib_Revision); 
     195 
     196    // add codesets.library information 
     197    snprintf(request, REQUEST_SIZE, "%s&lib%d=codesets-%d%%2E%d", request, cnt++, CodesetsBase->lib_Version, 
     198                                                                                  CodesetsBase->lib_Revision); 
     199 
     200    // add AmiSSL library information 
     201    if(AmiSSLMasterBase != NULL) 
     202      snprintf(request, REQUEST_SIZE, "%s&lib%d=amissl-%d%%2E%d", request, cnt++, AmiSSLMasterBase->lib_Version, 
     203                                                                                  AmiSSLMasterBase->lib_Revision); 
     204 
     205    // add XPK library information 
     206    if(XpkBase != NULL) 
     207      snprintf(request, REQUEST_SIZE, "%s&lib%d=xpk-%d%%2E%d", request, cnt++, XpkBase->lib_Version, 
     208                                                                               XpkBase->lib_Revision); 
     209 
     210    // add openurl.library information 
     211    if((base = OpenLibrary("openurl.library", 0)) != NULL) 
     212    { 
     213      snprintf(request, REQUEST_SIZE, "%s&lib%d=openurl-%d%%2E%d", request, cnt++, base->lib_Version, 
     214                                                                                   base->lib_Revision); 
     215      CloseLibrary(base); 
     216    } 
     217 
     218    // encode the MUI version 
     219    cnt = 0; 
     220    snprintf(request, REQUEST_SIZE, "%s&mui=%d%%2E%d", request, MUIMasterBase->lib_Version, 
     221                                                                MUIMasterBase->lib_Revision); 
     222 
     223    // add TheBar.mcc version information 
     224    if((mccObj = MUI_NewObject(MUIC_TheBar, TAG_DONE)) != NULL) 
     225    { 
     226      snprintf(request, REQUEST_SIZE, "%s&mcc%d=thebar-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
     227                                                                                    xget(mccObj, MUIA_Revision)); 
     228      MUI_DisposeObject(mccObj); 
     229    } 
     230 
     231    // add TextEditor.mcc version information 
     232    if((mccObj = MUI_NewObject(MUIC_TextEditor, TAG_DONE)) != NULL) 
     233    { 
     234      snprintf(request, REQUEST_SIZE, "%s&mcc%d=texteditor-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
     235                                                                                        xget(mccObj, MUIA_Revision)); 
     236      MUI_DisposeObject(mccObj); 
     237    } 
     238 
     239    // add BetterString.mcc version information 
     240    if((mccObj = MUI_NewObject(MUIC_BetterString, TAG_DONE)) != NULL) 
     241    { 
     242      snprintf(request, REQUEST_SIZE, "%s&mcc%d=betterstring-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
     243                                                                                          xget(mccObj, MUIA_Revision)); 
     244      MUI_DisposeObject(mccObj); 
     245    } 
     246 
     247    // add NList.mcc version information 
     248    if((mccObj = MUI_NewObject(MUIC_NList, TAG_DONE)) != NULL) 
     249    { 
     250      snprintf(request, REQUEST_SIZE, "%s&mcc%d=nlist-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
     251                                                                                   xget(mccObj, MUIA_Revision)); 
     252      MUI_DisposeObject(mccObj); 
     253    } 
     254 
     255    // add NListview.mcc version information 
     256    if((mccObj = MUI_NewObject(MUIC_NListview, TAG_DONE)) != NULL) 
     257    { 
     258      snprintf(request, REQUEST_SIZE, "%s&mcc%d=nlistview-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
     259                                                                                       xget(mccObj, MUIA_Revision)); 
     260      MUI_DisposeObject(mccObj); 
     261    } 
     262 
     263    // add NFloattext.mcc version information 
     264    if((mccObj = MUI_NewObject(MUIC_NFloattext, TAG_DONE)) != NULL) 
     265    { 
     266      snprintf(request, REQUEST_SIZE, "%s&mcc%d=nfloattext-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
     267                                                                                        xget(mccObj, MUIA_Revision)); 
     268      MUI_DisposeObject(mccObj); 
     269    } 
     270 
     271    // add NListtree.mcc version information 
     272    if((mccObj = MUI_NewObject(MUIC_NListtree, TAG_DONE)) != NULL) 
     273    { 
     274      snprintf(request, REQUEST_SIZE, "%s&mcc%d=nlisttree-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
     275                                                                                       xget(mccObj, MUIA_Revision)); 
     276      MUI_DisposeObject(mccObj); 
     277    } 
     278 
     279    // add NBalance.mcc version information 
     280    if((mccObj = MUI_NewObject(MUIC_NBalance, TAG_DONE)) != NULL) 
     281    { 
     282      snprintf(request, REQUEST_SIZE, "%s&mcc%d=nbalance-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
     283                                                                                      xget(mccObj, MUIA_Revision)); 
     284      MUI_DisposeObject(mccObj); 
     285    } 
     286  } 
     287 
     288  RETURN(request); 
     289  return request; 
     290} 
     291 
     292/// 
     293/// ParseUpdateFile 
     294// parse the downloaded update file and add the found components to the update 
     295// notify window 
     296BOOL ParseUpdateFile(const char *filename, const BOOL quiet) 
     297{ 
     298  BOOL result = FALSE; 
     299  FILE *fp; 
     300 
     301  ENTER(); 
     302 
     303  if((fp = fopen(filename, "r")) != NULL) 
     304  { 
     305    BOOL validUpdateCheck = FALSE; 
     306    BOOL updatesAvailable = FALSE; 
     307    struct UpdateComponent *comp = NULL; 
     308    char *buffer = NULL; 
     309    size_t size = 0; 
     310 
     311    setvbuf(fp, NULL, _IOFBF, SIZE_FILEBUF); 
     312 
     313    // make sure we clear the update window 
     314    DoMethod(G->UpdateNotifyWinObject, MUIM_UpdateNotifyWindow_Clear); 
     315 
     316    while(GetLine(&buffer, &size, fp) >= 0) 
     317    { 
     318      // make sure we trim the line by stripping leading 
     319      // and trailing spaces. 
     320      char *p = Trim(buffer); 
     321 
     322      D(DBF_UPDATE, "'%s'", p); 
     323 
     324      if(stricmp(p, "<updatecheck>") == 0) 
     325      { 
     326        validUpdateCheck = TRUE; 
     327      } 
     328      else if(stricmp(p, "</updatecheck>") == 0) 
     329      { 
     330        // break out as the update check signals to exit 
     331        break; 
     332      } 
     333      else if(validUpdateCheck == FALSE) 
     334      { 
     335        // we skip all lines until we found the <updatecheck> tag 
     336        continue; 
     337      } 
     338      else if(stricmp(p, "<component>") == 0) 
     339      { 
     340        // if we find an '<component>' tag, we can go and create an 
     341        // update notify window in advance and fill it according to the 
     342        // followed information 
     343 
     344        // if we still have an update component structure 
     345        // waiting to be submitted to our window we do it right 
     346        // away. 
     347        if(comp != NULL) 
    173348        { 
    174           char buf[SIZE_LINE]; 
    175           Object *mccObj; 
    176           struct Library *base; 
    177           unsigned short cnt = 0; 
    178  
    179           // encode the yam version 
    180           if(urlencode(buf, yamversion, sizeof(buf)) > 0) 
    181             snprintf(request, REQUEST_SIZE, "?ver=%s", buf); 
    182  
    183           // encode the yam buildid if present 
    184           if(urlencode(buf, yambuildid, sizeof(buf)) > 0) 
    185             snprintf(request, REQUEST_SIZE, "%s&buildid=%s", request, buf); 
    186  
    187           // encode the yam builddate if present 
    188           if(urlencode(buf, yamversiondate, sizeof(buf)) > 0) 
    189             snprintf(request, REQUEST_SIZE, "%s&builddate=%s", request, buf); 
    190  
    191           // encode the language in which YAM is running 
    192           if(G->Catalog != NULL && urlencode(buf, G->Catalog->cat_Language, sizeof(buf)) > 0) 
    193             snprintf(request, REQUEST_SIZE, "%s&lang=%s%%20%d%%2E%d", request, buf, G->Catalog->cat_Version, 
    194                                                                                     G->Catalog->cat_Revision); 
    195  
    196           // Now we add some third party components 
    197           // information for our update server as well. 
    198  
    199           // encode the exec version 
    200           snprintf(request, REQUEST_SIZE, "%s&exec=%d%%2E%d", request, ((struct Library *)SysBase)->lib_Version, 
    201                                                                        ((struct Library *)SysBase)->lib_Revision); 
    202  
    203           // add codesets.library information 
    204           snprintf(request, REQUEST_SIZE, "%s&lib%d=codesets-%d%%2E%d", request, cnt++, CodesetsBase->lib_Version, 
    205                                                                                         CodesetsBase->lib_Revision); 
    206  
    207           // add AmiSSL library information 
    208           if(AmiSSLMasterBase != NULL) 
    209             snprintf(request, REQUEST_SIZE, "%s&lib%d=amissl-%d%%2E%d", request, cnt++, AmiSSLMasterBase->lib_Version, 
    210                                                                                         AmiSSLMasterBase->lib_Revision); 
    211  
    212           // add XPK library information 
    213           if(XpkBase != NULL) 
    214             snprintf(request, REQUEST_SIZE, "%s&lib%d=xpk-%d%%2E%d", request, cnt++, XpkBase->lib_Version, 
    215                                                                                      XpkBase->lib_Revision); 
    216  
    217           // add openurl.library information 
    218           if((base = OpenLibrary("openurl.library", 0)) != NULL) 
     349          DoMethod(G->UpdateNotifyWinObject, MUIM_UpdateNotifyWindow_AddComponent, comp); 
     350          comp = NULL; 
     351        } 
     352 
     353        // make sure that we know that we have updates available also 
     354        // later on. 
     355        updatesAvailable = TRUE; 
     356 
     357        // create a new UpdateComponent structure which we 
     358        // are going to fill step by step 
     359        if((comp = calloc(sizeof(*comp), 1)) == NULL) 
     360        { 
     361          updatesAvailable = FALSE; 
     362          break; 
     363        } 
     364      } 
     365      else if(stricmp(p, "</component>") == 0) 
     366      { 
     367        if(comp != NULL) 
     368        { 
     369          DoMethod(G->UpdateNotifyWinObject, MUIM_UpdateNotifyWindow_AddComponent, comp); 
     370          comp = NULL; 
     371        } 
     372      } 
     373      else if(comp != NULL) 
     374      { 
     375        if(strnicmp(p, "NAME: ", 6) == 0) 
     376          strlcpy(comp->name, p+6, sizeof(comp->name)); 
     377        else if(strnicmp(p, "RECENT: ", 7) == 0) 
     378          strlcpy(comp->recent, p+7, sizeof(comp->recent)); 
     379        else if(strnicmp(p, "INSTALLED: ", 11) == 0) 
     380          strlcpy(comp->installed, p+11, sizeof(comp->installed)); 
     381        else if(strnicmp(p, "URL: ", 5) == 0) 
     382          strlcpy(comp->url, p+5, sizeof(comp->url)); 
     383        else if(stricmp(p, "<changelog>") == 0) 
     384        { 
     385          // we put the changelog text into a temporary file 
     386          if((comp->changeLogFile = OpenTempFile("w")) != NULL) 
    219387          { 
    220             snprintf(request, REQUEST_SIZE, "%s&lib%d=openurl-%d%%2E%d", request, cnt++, base->lib_Version, 
    221                                                                                          base->lib_Revision); 
    222             CloseLibrary(base); 
    223           } 
    224  
    225           // encode the MUI version 
    226           cnt = 0; 
    227           snprintf(request, REQUEST_SIZE, "%s&mui=%d%%2E%d", request, MUIMasterBase->lib_Version, 
    228                                                                       MUIMasterBase->lib_Revision); 
    229  
    230           // add TheBar.mcc version information 
    231           if((mccObj = MUI_NewObject(MUIC_TheBar, TAG_DONE)) != NULL) 
    232           { 
    233             snprintf(request, REQUEST_SIZE, "%s&mcc%d=thebar-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
    234                                                                                           xget(mccObj, MUIA_Revision)); 
    235             MUI_DisposeObject(mccObj); 
    236           } 
    237  
    238           // add TextEditor.mcc version information 
    239           if((mccObj = MUI_NewObject(MUIC_TextEditor, TAG_DONE)) != NULL) 
    240           { 
    241             snprintf(request, REQUEST_SIZE, "%s&mcc%d=texteditor-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
    242                                                                                               xget(mccObj, MUIA_Revision)); 
    243             MUI_DisposeObject(mccObj); 
    244           } 
    245  
    246           // add BetterString.mcc version information 
    247           if((mccObj = MUI_NewObject(MUIC_BetterString, TAG_DONE)) != NULL) 
    248           { 
    249             snprintf(request, REQUEST_SIZE, "%s&mcc%d=betterstring-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
    250                                                                                                 xget(mccObj, MUIA_Revision)); 
    251             MUI_DisposeObject(mccObj); 
    252           } 
    253  
    254           // add NList.mcc version information 
    255           if((mccObj = MUI_NewObject(MUIC_NList, TAG_DONE)) != NULL) 
    256           { 
    257             snprintf(request, REQUEST_SIZE, "%s&mcc%d=nlist-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
    258                                                                                          xget(mccObj, MUIA_Revision)); 
    259             MUI_DisposeObject(mccObj); 
    260           } 
    261  
    262           // add NListview.mcc version information 
    263           if((mccObj = MUI_NewObject(MUIC_NListview, TAG_DONE)) != NULL) 
    264           { 
    265             snprintf(request, REQUEST_SIZE, "%s&mcc%d=nlistview-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
    266                                                                                              xget(mccObj, MUIA_Revision)); 
    267             MUI_DisposeObject(mccObj); 
    268           } 
    269  
    270           // add NFloattext.mcc version information 
    271           if((mccObj = MUI_NewObject(MUIC_NFloattext, TAG_DONE)) != NULL) 
    272           { 
    273             snprintf(request, REQUEST_SIZE, "%s&mcc%d=nfloattext-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
    274                                                                                               xget(mccObj, MUIA_Revision)); 
    275             MUI_DisposeObject(mccObj); 
    276           } 
    277  
    278           // add NListtree.mcc version information 
    279           if((mccObj = MUI_NewObject(MUIC_NListtree, TAG_DONE)) != NULL) 
    280           { 
    281             snprintf(request, REQUEST_SIZE, "%s&mcc%d=nlisttree-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
    282                                                                                              xget(mccObj, MUIA_Revision)); 
    283             MUI_DisposeObject(mccObj); 
    284           } 
    285  
    286           // add NBalance.mcc version information 
    287           if((mccObj = MUI_NewObject(MUIC_NBalance, TAG_DONE)) != NULL) 
    288           { 
    289             snprintf(request, REQUEST_SIZE, "%s&mcc%d=nbalance-%ld%%2E%ld", request, cnt++, xget(mccObj, MUIA_Version), 
    290                                                                                             xget(mccObj, MUIA_Revision)); 
    291             MUI_DisposeObject(mccObj); 
    292           } 
    293  
    294           D(DBF_UPDATE, "send update request: '%s' (%ld)", request, strlen(request)); 
    295  
    296           // now we send a specific request via TR_DownloadURL() to 
    297           // our update server 
    298           if(TR_DownloadURL(conn, C->UpdateServer, request, tf->Filename) == TRUE) 
    299           { 
    300             // now we parse the result. 
    301             if((tf->FP = fopen(tf->Filename, "r")) != NULL) 
     388            FILE *out = comp->changeLogFile->FP; 
     389 
     390            while(GetLine(&buffer, &size, fp) >= 0L) 
    302391            { 
    303               BOOL validUpdateCheck = FALSE; 
    304               BOOL updatesAvailable = FALSE; 
    305               struct UpdateComponent *comp = NULL; 
    306               char *buffer = NULL; 
    307               size_t size = 0; 
    308  
    309               setvbuf(tf->FP, NULL, _IOFBF, SIZE_FILEBUF); 
    310  
    311               // make sure we clear an eventually existing update window 
    312               if(G->UpdateNotifyWinObject != NULL) 
    313                 DoMethod(G->UpdateNotifyWinObject, MUIM_UpdateNotifyWindow_Clear); 
    314  
    315               while(GetLine(&buffer, &size, tf->FP) >= 0) 
     392              D(DBF_UPDATE, "%s", buffer); 
     393 
     394              if(stricmp(buffer, "</changelog>") == 0) 
    316395              { 
    317                 // make sure we trim the line by stripping leading 
    318                 // and trailing spaces. 
    319                 char *p = Trim(buffer); 
    320  
    321                 D(DBF_UPDATE, "'%s'", p); 
    322  
    323                 if(stricmp(p, "<updatecheck>") == 0) 
    324                 { 
    325                   validUpdateCheck = TRUE; 
    326                 } 
    327                 else if(stricmp(p, "</updatecheck>") == 0) 
    328                 { 
    329                   // break out as the update check signals to exit 
    330                   break; 
    331                 } 
    332                 else if(validUpdateCheck == FALSE) 
    333                 { 
    334                   // we skip all lines until we found the <updatecheck> tag 
    335                   continue; 
    336                 } 
    337                 else if(stricmp(p, "<component>") == 0) 
    338                 { 
    339                   // if we find an '<component>' tag, we can go and create an 
    340                   // update notify window in advance and fill it according to the 
    341                   // followed information 
    342  
    343                   // make sure that we have created the update notification 
    344                   // window in advance. 
    345                   if(G->UpdateNotifyWinObject == NULL) 
    346                   { 
    347                     if((G->UpdateNotifyWinObject = UpdateNotifyWindowObject, End) == NULL) 
    348                       break; 
    349                   } 
    350  
    351                   // if we still have an update component structure 
    352                   // waiting to be submitted to our window we do it right 
    353                   // away. 
    354                   if(comp != NULL) 
    355                   { 
    356                     DoMethod(G->UpdateNotifyWinObject, MUIM_UpdateNotifyWindow_AddComponent, comp); 
    357                     comp = NULL; 
    358                   } 
    359  
    360                   // make sure that we know that we have updates available also 
    361                   // later on. 
    362                   updatesAvailable = TRUE; 
    363  
    364                   // create a new UpdateComponent structure which we 
    365                   // are going to fill step by step 
    366                   if((comp = calloc(sizeof(*comp), 1)) == NULL) 
    367                   { 
    368                     updatesAvailable = FALSE; 
    369                     break; 
    370                   } 
    371                 } 
    372                 else if(stricmp(p, "</component>") == 0) 
    373                 { 
    374                   if(comp != NULL) 
    375                   { 
    376                     DoMethod(G->UpdateNotifyWinObject, MUIM_UpdateNotifyWindow_AddComponent, comp); 
    377                     comp = NULL; 
    378                   } 
    379                 } 
    380                 else if(comp != NULL) 
    381                 { 
    382                   if(strnicmp(p, "NAME: ", 6) == 0) 
    383                     strlcpy(comp->name, p+6, sizeof(comp->name)); 
    384                   else if(strnicmp(p, "RECENT: ", 7) == 0) 
    385                     strlcpy(comp->recent, p+7, sizeof(comp->recent)); 
    386                   else if(strnicmp(p, "INSTALLED: ", 11) == 0) 
    387                     strlcpy(comp->installed, p+11, sizeof(comp->installed)); 
    388                   else if(strnicmp(p, "URL: ", 5) == 0) 
    389                     strlcpy(comp->url, p+5, sizeof(comp->url)); 
    390                   else if(stricmp(p, "<changelog>") == 0) 
    391                   { 
    392                     // we put the changelog text into a temporary file 
    393                     if((comp->changeLogFile = OpenTempFile("w")) != NULL) 
    394                     { 
    395                       FILE *out = comp->changeLogFile->FP; 
    396  
    397                       while(GetLine(&buffer, &size, tf->FP) >= 0L) 
    398                       { 
    399                         D(DBF_UPDATE, "%s", buffer); 
    400  
    401                         if(stricmp(buffer, "</changelog>") == 0) 
    402                         { 
    403                           // break out 
    404                           break; 
    405                         } 
    406                         else 
    407                           fprintf(out, "%s\n", buffer); 
    408                       } 
    409  
    410                       fclose(out); 
    411                       comp->changeLogFile->FP = NULL; 
    412                     } 
    413                   } 
    414                 } 
    415               } 
    416  
    417               // make sure we submitted all update components to our 
    418               // notify window. 
    419               if(comp != NULL) 
    420               { 
    421                 DoMethod(G->UpdateNotifyWinObject, MUIM_UpdateNotifyWindow_AddComponent, comp); 
    422                 comp = NULL; 
    423               } 
    424  
    425               // make sure we show the update notify window. 
    426               if(updatesAvailable == TRUE) 
    427               { 
    428                 set(G->UpdateNotifyWinObject, MUIA_Window_Open, TRUE); 
    429                 LastUpdateState.LastUpdateStatus = UST_UPDATESUCCESS; 
     396                // break out 
     397                break; 
    430398              } 
    431399              else 
    432               { 
    433                 // we didn't find any new updates 
    434                 LastUpdateState.LastUpdateStatus = UST_NOUPDATE; 
    435  
    436                 // show a requester if the check was triggered by the user 
    437                 if(quiet == FALSE) 
    438                   MUI_Request(G->App, NULL, 0, tr(MSG_UPD_NO_UPDATES_FOUND_TITLE), tr(MSG_Okay), tr(MSG_UPD_NO_UPDATES_FOUND), (C->UpdateInterval > 0) ? tr(MSG_UPD_NO_UPDATES_FOUND_HINT_AUTOCHECK) : tr(MSG_UPD_NO_UPDATES_FOUND_HINT_NOAUTOCHECK)); 
    439               } 
    440  
    441               // the updatecheck was successfull 
    442               result = TRUE; 
    443  
    444               fclose(tf->FP); 
    445               tf->FP = NULL; 
    446  
    447               free(buffer); 
     400                fprintf(out, "%s\n", buffer); 
    448401            } 
    449             else 
    450               ER_NewError(tr(MSG_ER_CantOpenTempfile), tf->Filename); 
     402 
     403            fclose(out); 
     404            comp->changeLogFile->FP = NULL; 
    451405          } 
    452  
    453           free(request); 
    454406        } 
    455  
    456         BusyEnd(); 
    457  
    458         CloseTempFile(tf); 
    459       } 
     407      } 
     408    } 
     409 
     410    // make sure we submitted all update components to our 
     411    // notify window. 
     412    if(comp != NULL) 
     413    { 
     414      DoMethod(G->UpdateNotifyWinObject, MUIM_UpdateNotifyWindow_AddComponent, comp); 
     415      comp = NULL; 
     416    } 
     417 
     418    // make sure we show the update notify window. 
     419    if(updatesAvailable == TRUE) 
     420    { 
     421      set(G->UpdateNotifyWinObject, MUIA_Window_Open, TRUE); 
     422      LastUpdateState.LastUpdateStatus = UST_UPDATESUCCESS; 
    460423    } 
    461424    else 
    462       ER_NewError(tr(MSG_ER_OPENTCPIP)); 
    463  
    464     // enable the transfer buttons in the toolbar again 
    465     MA_ChangeTransfer(TRUE); 
    466  
    467     // resume the mail check timer 
    468     ResumeTimer(TIMER_CHECKMAIL); 
    469  
    470     DeleteConnection(conn); 
    471   } 
     425    { 
     426      // we didn't find any new updates 
     427      LastUpdateState.LastUpdateStatus = UST_NOUPDATE; 
     428 
     429      // show a requester if the check was triggered by the user 
     430      if(quiet == FALSE) 
     431        MUI_Request(G->App, NULL, 0, tr(MSG_UPD_NO_UPDATES_FOUND_TITLE), tr(MSG_Okay), tr(MSG_UPD_NO_UPDATES_FOUND), (C->UpdateInterval > 0) ? tr(MSG_UPD_NO_UPDATES_FOUND_HINT_AUTOCHECK) : tr(MSG_UPD_NO_UPDATES_FOUND_HINT_NOAUTOCHECK)); 
     432    } 
     433 
     434    // the updatecheck was successfull 
     435    result = TRUE; 
     436 
     437    fclose(fp); 
     438 
     439    free(buffer); 
     440  } 
     441  else 
     442    ER_NewError(tr(MSG_ER_CantOpenTempfile), filename); 
    472443 
    473444  // as the last operation we get the current time as the 
     
    497468  return result; 
    498469} 
    499 /// 
     470 
     471// 
    500472/// LoadUpdateState 
    501473// Load update state file from disk 
     
    568540  LEAVE(); 
    569541} 
     542 
    570543/// 
    571544/// SaveUpdateState 
     
    594567  LEAVE(); 
    595568} 
     569 
    596570/// 
    597571/// GetLastUpdateState 
     
    609583  LEAVE(); 
    610584} 
     585 
    611586/// 
    612587/// SetDefaultUpdateState 
     
    621596  LEAVE(); 
    622597} 
    623 /// 
    624  
     598 
     599/// 
  • trunk/src/UpdateCheck.h

    r5441 r5442  
    6363// externally accessible functions 
    6464void InitUpdateCheck(const BOOL initial); 
    65 BOOL CheckForUpdates(const BOOL quiet); 
     65void CheckForUpdates(const BOOL quiet); 
     66char *BuildUpdateRequest(void); 
     67BOOL ParseUpdateFile(const char *filename, const BOOL quiet); 
    6668void LoadUpdateState(void); 
    6769void SaveUpdateState(void); 
  • trunk/src/YAM_MA.c

    r5441 r5442  
    24302430    SET_FLAG(msn->flags, MSF_IN_USE); 
    24312431 
    2432     success = DoAction(TA_ReceiveMails, TT_ReceiveMails_MailServer, msn, 
    2433                                         TT_ReceiveMails_Flags, flags, 
    2434                                         TT_ReceiveMails_Result, dlResult, 
    2435                                         TAG_DONE); 
     2432    success = DoAction(NULL, TA_ReceiveMails, TT_ReceiveMails_MailServer, msn, 
     2433                                              TT_ReceiveMails_Flags, flags, 
     2434                                              TT_ReceiveMails_Result, dlResult, 
     2435                                              TAG_DONE); 
    24362436    if(success == FALSE) 
    24372437    { 
     
    25612561      if(mlist != NULL) 
    25622562      { 
    2563         success = DoAction(TA_SendMails, TT_SendMails_MailServer, msn, 
    2564                                          TT_SendMails_Mails, mlist, 
    2565                                          TT_SendMails_Mode, mode, 
    2566                                          TAG_DONE); 
     2563        success = DoAction(NULL, TA_SendMails, TT_SendMails_MailServer, msn, 
     2564                                               TT_SendMails_Mails, mlist, 
     2565                                               TT_SendMails_Mode, mode, 
     2566                                               TAG_DONE); 
    25672567 
    25682568        // reset everything in case of failure 
     
    30093009      if(filename != NULL) 
    30103010      { 
    3011         success = DoAction(TA_ExportMails, TT_ExportMails_File, filename, 
    3012                                            TT_ExportMails_Mails, mlist, 
    3013                                            TT_ExportMails_Flags, flags, 
    3014                                            TAG_DONE); 
     3011        success = DoAction(NULL, TA_ExportMails, TT_ExportMails_File, filename, 
     3012                                                 TT_ExportMails_Mails, mlist, 
     3013                                                 TT_ExportMails_Flags, flags, 
     3014                                                 TAG_DONE); 
    30153015      } 
    30163016    } 
     
    30423042  if(actfo != NULL && isGroupFolder(actfo) == FALSE) 
    30433043  { 
    3044     result = DoAction(TA_ImportMails, TT_ImportMails_File, fname, 
    3045                                       TT_ImportMails_Folder, actfo, 
    3046                                       TT_ImportMails_Flags, flags, 
    3047                                       TAG_DONE); 
     3044    result = DoAction(NULL, TA_ImportMails, TT_ImportMails_File, fname, 
     3045                                            TT_ImportMails_Folder, actfo, 
     3046                                            TT_ImportMails_Flags, flags, 
     3047                                            TAG_DONE); 
    30483048  } 
    30493049 
  • trunk/src/YAM_RE.c

    r5441 r5442  
    36853685                      SET_FLAG(msn->flags, MSF_IN_USE); 
    36863686 
    3687                       mdnSent = DoAction(TA_SendMails, TT_SendMails_MailServer, msn, 
    3688                                                        TT_SendMails_Mails, mlist, 
    3689                                                        TT_SendMails_Mode, autoSend ? SENDMAIL_ACTIVE_AUTO : SENDMAIL_ACTIVE_USER, 
    3690                                                        TAG_DONE); 
     3687                      mdnSent = DoAction(NULL, TA_SendMails, TT_SendMails_MailServer, msn, 
     3688                                                             TT_SendMails_Mails, mlist, 
     3689                                                             TT_SendMails_Mode, autoSend ? SENDMAIL_ACTIVE_AUTO : SENDMAIL_ACTIVE_USER, 
     3690                                                             TAG_DONE); 
    36913691 
    36923692                      // clear the "in use" flag if the send process failed 
  • trunk/src/YAM_UT.c

    r5441 r5442  
    50545054 
    50555055    // let the thread framework do the dirty work 
    5056     result = DoAction(TA_LaunchCommand, TT_LaunchCommand_Command, cmd, 
    5057                                         TT_LaunchCommand_Output, outdef, 
    5058                                         TAG_DONE); 
     5056    result = DoAction(NULL, TA_LaunchCommand, TT_LaunchCommand_Command, cmd, 
     5057                                              TT_LaunchCommand_Output, outdef, 
     5058                                              TAG_DONE); 
    50595059  } 
    50605060  else 
  • trunk/src/mui/ClassesExtra.h

    r4469 r5442  
    164164#define _isinwholeobject(o,x,y)   (_between(_left(o),(x),_right (o)) && _between(_top(o) ,(y),_bottom(o))) 
    165165 
     166 
     167#define MUIM_ThreadFinished                        (TAG_USER | (0x2677 << 16)) 
     168 
     169struct MUIP_ThreadFinished { ULONG MethodID; ULONG action; LONG result; APTR actionTags; }; 
     170 
    166171#endif 
  • trunk/src/mui/UpdateNotifyWindow.c

    r5441 r5442  
    4949#include "Requesters.h" 
    5050#include "Themes.h" 
     51#include "Threads.h" 
    5152 
    5253#include "mui/ImageArea.h" 
     
    6465  char *ChangeLogText; 
    6566  char WindowTitle[SIZE_DEFAULT]; 
     67  struct TempFile *tempFile; 
     68  BOOL quiet; 
    6669}; 
    6770*/ 
     
    7174OVERLOAD(OM_NEW) 
    7275{ 
    73   Object *bt_visit; 
    74   Object *bt_close; 
    75   Object *nl_componentlist; 
    76   Object *nf_componenthistory; 
    77   Object *ch_skipinfuture; 
    78  
    79   ENTER(); 
    80  
    81   if((obj = DoSuperNew(cl, obj, 
    82  
    83     MUIA_Window_ID,         MAKE_ID('U','P','D','1'), 
    84     MUIA_Window_Title,      tr(MSG_UPD_NOTIFICATION_WTITLE), 
    85     MUIA_Window_Height,     MUIV_Window_Height_MinMax(30), 
    86     MUIA_Window_Width,      MUIV_Window_Width_MinMax(30), 
    87     MUIA_Window_RefWindow,  G->MA->GUI.WI, 
    88     WindowContents, VGroup, 
    89  
    90       Child, HGroup, 
    91         Child, MakeImageObject("config_update_big", G->theme.configImages[ci_UpdateBig]), 
    92         Child, VGroup, 
    93           Child, TextObject, 
    94             MUIA_Text_PreParse, "\033b", 
    95             MUIA_Text_Contents, tr(MSG_UPD_NOTIFICATION_TITLE), 
    96             MUIA_Weight,        100, 
     76  struct TempFile *tempFile; 
     77 
     78  ENTER(); 
     79 
     80  if((tempFile = OpenTempFile(NULL)) != NULL) 
     81  { 
     82    Object *bt_visit; 
     83    Object *bt_close; 
     84    Object *nl_componentlist; 
     85    Object *nf_componenthistory; 
     86    Object *ch_skipinfuture; 
     87 
     88    if((obj = DoSuperNew(cl, obj, 
     89 
     90      MUIA_Window_ID,         MAKE_ID('U','P','D','1'), 
     91      MUIA_Window_Title,      tr(MSG_UPD_NOTIFICATION_WTITLE), 
     92      MUIA_Window_Height,     MUIV_Window_Height_MinMax(30), 
     93      MUIA_Window_Width,      MUIV_Window_Width_MinMax(30), 
     94      MUIA_Window_RefWindow,  G->MA->GUI.WI, 
     95      WindowContents, VGroup, 
     96 
     97        Child, HGroup, 
     98          Child, MakeImageObject("config_update_big", G->theme.configImages[ci_UpdateBig]), 
     99          Child, VGroup, 
     100            Child, TextObject, 
     101              MUIA_Text_PreParse, "\033b", 
     102              MUIA_Text_Contents, tr(MSG_UPD_NOTIFICATION_TITLE), 
     103              MUIA_Weight,        100, 
     104            End, 
     105            Child, TextObject, 
     106              MUIA_Text_Contents, tr(MSG_UPD_NOTIFICATION_SUMMARY), 
     107              MUIA_Font,          MUIV_Font_Tiny, 
     108              MUIA_Weight,        100, 
     109            End, 
    97110          End, 
    98           Child, TextObject, 
    99             MUIA_Text_Contents, tr(MSG_UPD_NOTIFICATION_SUMMARY), 
    100             MUIA_Font,          MUIV_Font_Tiny, 
    101             MUIA_Weight,        100, 
     111        End, 
     112 
     113        Child, RectangleObject, 
     114          MUIA_Rectangle_HBar, TRUE, 
     115          MUIA_FixHeight,      4, 
     116        End, 
     117 
     118        Child, NListviewObject, 
     119          MUIA_CycleChain, TRUE, 
     120          MUIA_VertWeight, 20, 
     121          MUIA_Listview_DragType,  MUIV_Listview_DragType_None, 
     122          MUIA_NListview_NList, nl_componentlist = UpdateComponentListObject, 
    102123          End, 
    103124        End, 
     125 
     126        Child, NBalanceObject, End, 
     127 
     128        Child, TextObject, 
     129          MUIA_Text_Contents, tr(MSG_UPD_NOTIFICATION_CHANGES), 
     130          MUIA_Font,          MUIV_Font_Tiny, 
     131        End, 
     132        Child, NListviewObject, 
     133          MUIA_CycleChain, TRUE, 
     134          MUIA_NListview_NList, nf_componenthistory = NFloattextObject, 
     135            MUIA_Font,             MUIV_Font_Fixed, 
     136            MUIA_NList_Format,     "P=\33l", 
     137            MUIA_NList_Input,      FALSE, 
     138            MUIA_NFloattext_Text,  "", 
     139          End, 
     140        End, 
     141 
     142        Child, HGroup, 
     143          Child, ch_skipinfuture = MakeCheck(tr(MSG_UPD_NOTIFICATION_NOUPDATE)), 
     144          Child, LLabel1(tr(MSG_UPD_NOTIFICATION_NOUPDATE)), 
     145          Child, HVSpace, 
     146        End, 
     147 
     148        Child, RectangleObject, 
     149          MUIA_Rectangle_HBar, TRUE, 
     150          MUIA_FixHeight,      4, 
     151        End, 
     152 
     153        Child, HGroup, 
     154          Child, HVSpace, 
     155          Child, HVSpace, 
     156          Child, bt_close = MakeButton(tr(MSG_UPD_NOTIFICATION_CLOSE)), 
     157          Child, bt_visit = MakeButton(tr(MSG_UPD_NOTIFICATION_VISITURL)), 
     158        End, 
     159 
    104160      End, 
    105161 
    106       Child, RectangleObject, 
    107         MUIA_Rectangle_HBar, TRUE, 
    108         MUIA_FixHeight,      4, 
    109       End, 
    110  
    111       Child, NListviewObject, 
    112         MUIA_CycleChain, TRUE, 
    113         MUIA_VertWeight, 20, 
    114         MUIA_Listview_DragType,  MUIV_Listview_DragType_None, 
    115         MUIA_NListview_NList, nl_componentlist = UpdateComponentListObject, 
    116         End, 
    117       End, 
    118  
    119       Child, NBalanceObject, End, 
    120  
    121       Child, TextObject, 
    122         MUIA_Text_Contents, tr(MSG_UPD_NOTIFICATION_CHANGES), 
    123         MUIA_Font,          MUIV_Font_Tiny, 
    124       End, 
    125       Child, NListviewObject, 
    126         MUIA_CycleChain, TRUE, 
    127         MUIA_NListview_NList, nf_componenthistory = NFloattextObject, 
    128           MUIA_Font,             MUIV_Font_Fixed, 
    129           MUIA_NList_Format,     "P=\33l", 
    130           MUIA_NList_Input,      FALSE, 
    131           MUIA_NFloattext_Text,  "", 
    132         End, 
    133       End, 
    134  
    135       Child, HGroup, 
    136         Child, ch_skipinfuture = MakeCheck(tr(MSG_UPD_NOTIFICATION_NOUPDATE)), 
    137         Child, LLabel1(tr(MSG_UPD_NOTIFICATION_NOUPDATE)), 
    138         Child, HVSpace, 
    139       End, 
    140  
    141       Child, RectangleObject, 
    142         MUIA_Rectangle_HBar, TRUE, 
    143         MUIA_FixHeight,      4, 
    144       End, 
    145  
    146       Child, HGroup, 
    147         Child, HVSpace, 
    148         Child, HVSpace, 
    149         Child, bt_close = MakeButton(tr(MSG_UPD_NOTIFICATION_CLOSE)), 
    150         Child, bt_visit = MakeButton(tr(MSG_UPD_NOTIFICATION_VISITURL)), 
    151       End, 
    152  
    153     End, 
    154  
    155     TAG_MORE, inittags(msg))) != NULL) 
    156   { 
    157     GETDATA; 
    158  
    159     DoMethod(G->App, OM_ADDMEMBER, obj); 
    160  
    161     data->ComponentList = nl_componentlist; 
    162     data->ComponentHistory = nf_componenthistory; 
    163     data->SkipInFutureCheckBox = ch_skipinfuture; 
    164     data->VisitURLButton = bt_visit; 
    165  
    166     // start with a disabled "Visit URL" button 
    167     set(bt_visit, MUIA_Disabled, TRUE); 
    168  
    169     DoMethod(obj,               MUIM_Notify, MUIA_Window_CloseRequest, TRUE, MUIV_Notify_Self, 3, METHOD(Close)); 
    170     DoMethod(nl_componentlist,  MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, obj, 2, METHOD(Select), MUIV_TriggerValue); 
    171     DoMethod(nl_componentlist,  MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, obj, 1, METHOD(VisitURL)); 
    172     DoMethod(bt_visit,          MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, METHOD(VisitURL)); 
    173     DoMethod(bt_close,          MUIM_Notify, MUIA_Pressed, FALSE, obj, 3, METHOD(Close)); 
    174  
    175     set(obj, MUIA_Window_Activate, TRUE); 
    176   } 
     162      TAG_MORE, inittags(msg))) != NULL) 
     163    { 
     164      GETDATA; 
     165 
     166      DoMethod(G->App, OM_ADDMEMBER, obj); 
     167 
     168      data->ComponentList = nl_componentlist; 
     169      data->ComponentHistory = nf_componenthistory; 
     170      data->SkipInFutureCheckBox = ch_skipinfuture; 
     171      data->VisitURLButton = bt_visit; 
     172      data->tempFile = tempFile; 
     173 
     174      // start with a disabled "Visit URL" button 
     175      set(bt_visit, MUIA_Disabled, TRUE); 
     176 
     177      DoMethod(obj,               MUIM_Notify, MUIA_Window_CloseRequest, TRUE, MUIV_Notify_Self, 3, METHOD(Close)); 
     178      DoMethod(nl_componentlist,  MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime, obj, 2, METHOD(Select), MUIV_TriggerValue); 
     179      DoMethod(nl_componentlist,  MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, obj, 1, METHOD(VisitURL)); 
     180      DoMethod(bt_visit,          MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, METHOD(VisitURL)); 
     181      DoMethod(bt_close,          MUIM_Notify, MUIA_Pressed, FALSE, obj, 3, METHOD(Close)); 
     182 
     183      set(obj, MUIA_Window_Activate, TRUE); 
     184    } 
     185    else 
     186      CloseTempFile(tempFile); 
     187  } 
     188  else 
     189    obj = NULL; 
    177190 
    178191  RETURN((IPTR)obj); 
     
    181194 
    182195/// 
     196/// OVERLOAD(OM_DISPOSE) 
     197OVERLOAD(OM_DISPOSE) 
     198{ 
     199  GETDATA; 
     200 
     201  CloseTempFile(data->tempFile); 
     202 
     203  return DoSuperMethodA(cl, obj, msg); 
     204} 
     205 
     206/// 
    183207/// OVERLOAD(OM_SET) 
    184208OVERLOAD(OM_SET) 
    185209{ 
    186210  GETDATA; 
    187  
    188211  struct TagItem *tags = inittags(msg), *tag; 
     212 
    189213  while((tag = NextTagItem((APTR)&tags)) != NULL) 
    190214  { 
     
    231255 
    232256/// 
     257/// OVERLOAD(MUIM_ThreadFinished) 
     258OVERLOAD(MUIM_ThreadFinished) 
     259{ 
     260  GETDATA; 
     261  struct MUIP_ThreadFinished *tf = (struct MUIP_ThreadFinished *)msg; 
     262 
     263  ENTER(); 
     264 
     265  // the thread which did the download has finished 
     266  // now parse the update file if the download was successful 
     267  if(tf->result == TRUE) 
     268    ParseUpdateFile(data->tempFile->Filename, data->quiet); 
     269 
     270  BusyEnd(); 
     271 
     272  LEAVE(); 
     273  return 0; 
     274} 
     275 
     276/// 
    233277 
    234278/* Public Methods */ 
     279/// DECLARE(CheckForUpdates) 
     280// set up and send an update request 
     281DECLARE(CheckForUpdates) // ULONG quiet 
     282{ 
     283  GETDATA; 
     284  char *request; 
     285 
     286  ENTER(); 
     287 
     288  if((request = BuildUpdateRequest()) != NULL) 
     289  { 
     290    D(DBF_UPDATE, "send update request '%s' (%ld)", request, strlen(request)); 
     291 
     292    BusyText(tr(MSG_BusyGettingVerInfo), ""); 
     293 
     294    // now we send a specific request via DownloadURL() to our update server 
     295    DoAction(obj, TA_DownloadURL, TT_DownloadURL_Server, C->UpdateServer, 
     296                                  TT_DownloadURL_Request, request, 
     297                                  TT_DownloadURL_Filename, data->tempFile->Filename, 
     298                                  TAG_DONE); 
     299    free(request); 
     300 
     301    // remember the "quiet" state of this check 
     302    data->quiet = msg->quiet; 
     303  } 
     304 
     305  LEAVE(); 
     306  return 0; 
     307} 
     308 
     309/// 
    235310/// DECLARE(Clear) 
    236311DECLARE(Clear) 
     
    246321  data->ChangeLogText = NULL; 
    247322 
    248   RETURN(0); 
     323  LEAVE(); 
    249324  return 0; 
    250325} 
     
    291366  } 
    292367 
    293   RETURN(0); 
     368  LEAVE(); 
    294369  return 0; 
    295370} 
     
    306381  DoMethod(data->ComponentList, MUIM_NList_InsertSingle, msg->comp, MUIV_NList_Insert_Bottom); 
    307382 
    308   RETURN(0); 
     383  LEAVE(); 
    309384  return 0; 
    310385} 
     
    334409  } 
    335410 
    336   RETURN(0); 
     411  LEAVE(); 
    337412  return 0; 
    338413} 
     
    362437  } 
    363438 
    364   if(CE) 
     439  if(CE != NULL) 
    365440  { 
    366441    // now we make sure the C and CE config structure is in sync again 
     
    376451  set(obj, MUIA_Window_Open, FALSE); 
    377452 
    378   RETURN(0); 
    379   return 0; 
    380 } 
    381  
    382 /// 
     453  LEAVE(); 
     454  return 0; 
     455} 
     456 
     457/// 
  • trunk/src/mui/WriteWindow.c

    r5441 r5442  
    42294229            SET_FLAG(msn->flags, MSF_IN_USE); 
    42304230 
    4231             mailSent = DoAction(TA_SendMails, TT_SendMails_MailServer, msn, 
    4232                                               TT_SendMails_Mails, mlist, 
    4233                                               TT_SendMails_Mode, SENDMAIL_ACTIVE_USER, 
    4234                                               TAG_DONE); 
     4231            mailSent = DoAction(NULL, TA_SendMails, TT_SendMails_MailServer, msn, 
     4232                                                    TT_SendMails_Mails, mlist, 
     4233                                                    TT_SendMails_Mode, SENDMAIL_ACTIVE_USER, 
     4234                                                    TAG_DONE); 
    42354235            if(mailSent == FALSE) 
    42364236              CLEAR_FLAG(msn->flags, MSF_IN_USE); 
  • trunk/src/rexx/geturl.c

    r4981 r5442  
    3434#include "Locale.h" 
    3535#include "Rexx.h" 
     36#include "Threads.h" 
    3637 
    37 #include "tcp/Connection.h" 
    3838#include "tcp/http.h" 
    3939 
     
    6262    case RXIF_ACTION: 
    6363    { 
    64       struct Connection *conn; 
     64      BusyText(tr(MSG_TR_Downloading), ""); 
    6565 
    66       if((conn = CreateConnection()) != NULL) 
     66      if(DoAction(NULL, TA_DownloadURL, TT_DownloadURL_Server, args->url, 
     67                                        TT_DownloadURL_Filename, args->filename, 
     68                                        TT_DownloadURL_Flags, DLURLF_SIGNAL, 
     69                                        TAG_DONE) == TRUE) 
    6770      { 
    68         if(ConnectionIsOnline(conn) == TRUE) 
    69         { 
    70           BusyText(tr(MSG_TR_Downloading), ""); 
    71  
    72           if(TR_DownloadURL(conn, args->url, NULL, args->filename) == FALSE) 
    73             params->rc = RETURN_ERROR; 
    74  
    75           BusyEnd(); 
    76         } 
    77         else 
    78           params->rc = RETURN_WARN; 
    79  
    80         DeleteConnection(conn); 
     71        MiniMainLoop(); 
    8172      } 
    8273      else 
    83         params->rc = RETURN_WARN; 
     74      { 
     75        params->rc = RETURN_ERROR; 
     76      } 
     77 
     78      BusyEnd(); 
    8479    } 
    8580    break; 
  • trunk/src/tcp/http.c

    r5387 r5442  
    3434 
    3535#include "Locale.h" 
     36#include "Threads.h" 
    3637 
    3738#include "tcp/Connection.h" 
     39#include "tcp/http.h" 
    3840 
    3941#include "Debug.h" 
    4042 
    41 /**************************************************************************/ 
    42 // static function prototypes 
    43  
    44 /**************************************************************************/ 
    45 // local macros & defines 
    46  
    47 /*************************************************************************** 
    48  Module: HTTP protocol 
    49 ***************************************************************************/ 
    50  
    51 /// TR_DownloadURL() 
    52 //  Downloads a file from the web using HTTP/1.1 (RFC 2616) 
    53 BOOL TR_DownloadURL(struct Connection *conn, const char *server, const char *request, const char *filename) 
     43struct TransferContext 
    5444{ 
    55   BOOL result = FALSE; 
    56   BOOL noproxy = (C->ProxyServer[0] == '\0'); 
     45  struct Connection *connection; 
    5746  int hport; 
    5847  char url[SIZE_URL]; 
    5948  char host[SIZE_HOST]; 
    60   char *path; 
    61   char *bufptr; 
     49  char serverPath[SIZE_LINE]; 
     50  char requestResponse[SIZE_LINE]; 
     51}; 
     52 
     53/// DownloadURL() 
     54//  Downloads a file from the web using HTTP/1.1 (RFC 2616) 
     55BOOL DownloadURL(const char *server, const char *request, const char *filename, const ULONG flags) 
     56{ 
     57  BOOL success = FALSE; 
     58  struct TransferContext *tc; 
    6259 
    6360  ENTER(); 
    6461 
    65   // extract the server address and strip the http:// part 
    66   // of the URI 
    67   if(strnicmp(server, "http://", 7) == 0) 
    68     strlcpy(url, &server[7], sizeof(url)); 
    69   else 
    70     strlcpy(url, server, sizeof(url)); 
    71  
    72   // in case an explicit request was given we 
    73   // add it here 
    74   if(request != NULL) 
     62  if((tc = calloc(1, sizeof(*tc))) != NULL) 
    7563  { 
    76     if(url[strlen(url)-1] != '/') 
    77       strlcat(url, "/", sizeof(url)); 
    78  
    79     strlcat(url, request, sizeof(url)); 
     64    if((tc->connection = CreateConnection()) != NULL && ConnectionIsOnline(tc->connection) == TRUE) 
     65    { 
     66      BOOL noproxy = (C->ProxyServer[0] == '\0'); 
     67      char *path; 
     68      char *bufptr; 
     69 
     70      // extract the server address and strip the http:// part 
     71      // of the URI 
     72      if(strnicmp(server, "http://", 7) == 0) 
     73        strlcpy(tc->url, &server[7], sizeof(tc->url)); 
     74      else 
     75        strlcpy(tc->url, server, sizeof(tc->url)); 
     76 
     77      // in case an explicit request was given we 
     78      // add it here 
     79      if(request != NULL) 
     80      { 
     81        if(tc->url[strlen(tc->url)-1] != '/') 
     82          strlcat(tc->url, "/", sizeof(tc->url)); 
     83 
     84        strlcat(tc->url, request, sizeof(tc->url)); 
     85      } 
     86 
     87      // find the first occurance of the '/' separator in out 
     88      // url and insert a terminating NUL character 
     89      if((path = strchr(tc->url, '/')) != NULL) 
     90        *path++ = '\0'; 
     91      else 
     92        path = (char *)""; 
     93 
     94      // extract the hostname from the URL or use the proxy server 
     95      // address if specified. 
     96      strlcpy(tc->host, noproxy ? tc->url : C->ProxyServer, sizeof(tc->host)); 
     97 
     98      // extract the port on which we connect if the 
     99      // hostname contain an ':' separator 
     100      if((bufptr = strchr(tc->host, ':')) != NULL) 
     101      { 
     102        *bufptr++ = '\0'; 
     103        tc->hport = atoi(bufptr); 
     104      } 
     105      else 
     106        tc->hport = noproxy ? 80 : 8080; 
     107 
     108      // open the TCP/IP connection to 'host' under the port 'hport' 
     109      if((ConnectToHost(tc->connection, tc->host, tc->hport)) == CONNECTERR_SUCCESS) 
     110      { 
     111        char *serverHost; 
     112        char *port; 
     113 
     114        // now we build the HTTP request we send out to the HTTP 
     115        // server 
     116        if(noproxy == TRUE) 
     117        { 
     118          snprintf(tc->serverPath, sizeof(tc->serverPath), "/%s", path); 
     119          serverHost = tc->host; 
     120        } 
     121        else if((port = strchr(tc->url, ':')) != NULL) 
     122        { 
     123          *port++ = '\0'; 
     124 
     125          snprintf(tc->serverPath, sizeof(tc->serverPath), "http://%s:%s/%s", tc->url, port, path); 
     126          serverHost = tc->url; 
     127        } 
     128        else 
     129        { 
     130          snprintf(tc->serverPath, sizeof(tc->serverPath), "http://%s/%s", tc->url, path); 
     131          serverHost = tc->url; 
     132        } 
     133 
     134        // construct the HTTP request 
     135        // we send a HTTP/1.0 request because 1.1 implies that we have to be able 
     136        // to deal with e.g. "Transfer-Encoding: chunked" responses which we can't handle 
     137        // right now. 
     138        snprintf(tc->requestResponse, sizeof(tc->requestResponse), "GET %s HTTP/1.0\r\n" 
     139                                                                   "Host: %s\r\n" 
     140                                                                   "User-Agent: %s\r\n" 
     141                                                                   "Connection: close\r\n" 
     142                                                                   "Accept: */*\r\n" 
     143                                                                   "\r\n", tc->serverPath, serverHost, yamuseragent); 
     144 
     145        SHOWSTRING(DBF_NET, tc->requestResponse); 
     146 
     147        // send out the httpRequest 
     148        if(SendLineToHost(tc->connection, tc->requestResponse) > 0) 
     149        { 
     150          char *p; 
     151          int len; 
     152 
     153          // now we read out the very first line to see if the 
     154          // response code matches and is fine 
     155          len = ReceiveLineFromHost(tc->connection, tc->requestResponse, sizeof(tc->requestResponse)); 
     156 
     157          SHOWSTRING(DBF_NET, tc->requestResponse); 
     158 
     159          // check the server response 
     160          if(len > 0 && strnicmp(tc->requestResponse, "HTTP/", 5) == 0 && 
     161             (p = strchr(tc->requestResponse, ' ')) != NULL && atoi(TrimStart(p)) == 200) 
     162          { 
     163            // we can request all further lines from our socket 
     164            // until we reach the entity body 
     165            while(tc->connection->error == CONNECTERR_NO_ERROR && 
     166                  (len = ReceiveLineFromHost(tc->connection, tc->requestResponse, sizeof(tc->requestResponse))) > 0) 
     167            { 
     168              // we scan for the end of the 
     169              // response header by searching for the first '\r\n' 
     170              // line 
     171              if(strcmp(tc->requestResponse, "\r\n") == 0) 
     172              { 
     173                FILE *out; 
     174 
     175                // prepare the output file. 
     176                if((out = fopen(filename, "w")) != NULL) 
     177                { 
     178                  LONG retrieved = -1; 
     179 
     180                  setvbuf(out, NULL, _IOFBF, SIZE_FILEBUF); 
     181 
     182                  // we seem to have reached the entity body, so 
     183                  // from here we retrieve everything we can get and 
     184                  // immediately write it out to a file. that's it :) 
     185                  while(tc->connection->error == CONNECTERR_NO_ERROR && 
     186                        (len = ReceiveLineFromHost(tc->connection, tc->requestResponse, sizeof(tc->requestResponse))) > 0) 
     187                  { 
     188                    if(fwrite(tc->requestResponse, len, 1, out) != 1) 
     189                    { 
     190                      retrieved = -1; // signal an error! 
     191                      break; 
     192                    } 
     193 
     194                    retrieved += len; 
     195                  } 
     196 
     197                  D(DBF_NET, "received %ld bytes", retrieved); 
     198 
     199                  // check if we retrieved anything 
     200                  if(tc->connection->error == CONNECTERR_NO_ERROR && retrieved >= 0) 
     201                    success = TRUE; 
     202 
     203                  fclose(out); 
     204                } 
     205                else 
     206                  ER_NewError(tr(MSG_ER_CantCreateFile), filename); 
     207 
     208                break; 
     209              } 
     210            } 
     211          } 
     212          else 
     213            ER_NewError(tr(MSG_ER_DocNotFound), path); 
     214        } 
     215        else 
     216          ER_NewError(tr(MSG_ER_SendHTTP)); 
     217      } 
     218      else 
     219        ER_NewError(tr(MSG_ER_ConnectHTTP), tc->host); 
     220 
     221      DisconnectFromHost(tc->connection); 
     222    } 
     223 
     224    DeleteConnection(tc->connection); 
     225    free(tc); 
    80226  } 
    81227 
    82   // find the first occurance of the '/' separator in out 
    83   // url and insert a terminating NUL character 
    84   if((path = strchr(url, '/')) != NULL) 
    85     *path++ = '\0'; 
    86   else 
    87     path = (char *)""; 
    88  
    89   // extract the hostname from the URL or use the proxy server 
    90   // address if specified. 
    91   strlcpy(host, noproxy ? url : C->ProxyServer, sizeof(host)); 
    92  
    93   // extract the port on which we connect if the 
    94   // hostname contain an ':' separator 
    95   if((bufptr = strchr(host, ':')) != NULL) 
    96   { 
    97     *bufptr++ = '\0'; 
    98     hport = atoi(bufptr); 
    99   } 
    100   else 
    101     hport = noproxy ? 80 : 8080; 
    102  
    103   // open the TCP/IP connection to 'host' under the port 'hport' 
    104   if((ConnectToHost(conn, host, hport)) == CONNECTERR_SUCCESS) 
    105   { 
    106     char *serverHost; 
    107     char serverPath[SIZE_LINE]; 
    108     char httpRequest[SIZE_LINE]; 
    109     char *port; 
    110  
    111     // now we build the HTTP request we send out to the HTTP 
    112     // server 
    113     if(noproxy) 
    114     { 
    115       snprintf(serverPath, sizeof(serverPath), "/%s", path); 
    116       serverHost = host; 
    117     } 
    118     else if((port = strchr(url, ':')) != NULL) 
    119     { 
    120       *port++ = '\0'; 
    121  
    122       snprintf(serverPath, sizeof(serverPath), "http://%s:%s/%s", url, port, path); 
    123       serverHost = url; 
    124     } 
    125     else 
    126     { 
    127       snprintf(serverPath, sizeof(serverPath), "http://%s/%s", url, path); 
    128       serverHost = url; 
    129     } 
    130  
    131     // construct the HTTP request 
    132     // we send a HTTP/1.0 request because 1.1 implies that we have to be able 
    133     // to deal with e.g. "Transfer-Encoding: chunked" responses which we can't handle 
    134     // right now. 
    135     snprintf(httpRequest, sizeof(httpRequest), "GET %s HTTP/1.0\r\n" 
    136                                                "Host: %s\r\n" 
    137                                                "User-Agent: %s\r\n" 
    138                                                "Connection: close\r\n" 
    139                                                "Accept: */*\r\n" 
    140                                                "\r\n", serverPath, serverHost, yamuseragent); 
    141  
    142     SHOWSTRING(DBF_NET, httpRequest); 
    143  
    144     // send out the httpRequest 
    145     if(SendLineToHost(conn, httpRequest) > 0) 
    146     { 
    147       char *p; 
    148       char serverResponse[SIZE_LINE]; 
    149       int len; 
    150  
    151       // clear the serverResponse string 
    152       serverResponse[0] = '\0'; 
    153  
    154       // now we read out the very first line to see if the 
    155       // response code matches and is fine 
    156       len = ReceiveLineFromHost(conn, serverResponse, sizeof(serverResponse)); 
    157  
    158       SHOWSTRING(DBF_NET, serverResponse); 
    159  
    160       // check the server response 
    161       if(len > 0 && strnicmp(serverResponse, "HTTP/", 5) == 0 && 
    162          (p = strchr(serverResponse, ' ')) != NULL && atoi(TrimStart(p)) == 200) 
    163       { 
    164         // we can request all further lines from our socket 
    165         // until we reach the entity body 
    166         while(conn->error == CONNECTERR_NO_ERROR && 
    167               (len = ReceiveLineFromHost(conn, serverResponse, sizeof(serverResponse))) > 0) 
    168         { 
    169           // we scan for the end of the 
    170           // response header by searching for the first '\r\n' 
    171           // line 
    172           if(strcmp(serverResponse, "\r\n") == 0) 
    173           { 
    174             FILE *out; 
    175  
    176             // prepare the output file. 
    177             if((out = fopen(filename, "w")) != NULL) 
    178             { 
    179               LONG retrieved = -1; 
    180  
    181               setvbuf(out, NULL, _IOFBF, SIZE_FILEBUF); 
    182  
    183               // we seem to have reached the entity body, so 
    184               // from here we retrieve everything we can get and 
    185               // immediately write it out to a file. that's it :) 
    186               while(conn->error == CONNECTERR_NO_ERROR && 
    187                     (len = ReceiveLineFromHost(conn, serverResponse, sizeof(serverResponse))) > 0) 
    188               { 
    189                 if(fwrite(serverResponse, len, 1, out) != 1) 
    190                 { 
    191                   retrieved = -1; // signal an error! 
    192                   break; 
    193                 } 
    194  
    195                 retrieved += len; 
    196               } 
    197  
    198               D(DBF_NET, "received %ld bytes", retrieved); 
    199  
    200               // check if we retrieved anything 
    201               if(conn->error == CONNECTERR_NO_ERROR && retrieved >= 0) 
    202                 result = TRUE; 
    203  
    204               fclose(out); 
    205             } 
    206             else 
    207               ER_NewError(tr(MSG_ER_CantCreateFile), filename); 
    208  
    209             break; 
    210           } 
    211         } 
    212       } 
    213       else 
    214         ER_NewError(tr(MSG_ER_DocNotFound), path); 
    215     } 
    216     else 
    217       ER_NewError(tr(MSG_ER_SendHTTP)); 
    218   } 
    219   else 
    220     ER_NewError(tr(MSG_ER_ConnectHTTP), host); 
    221  
    222   if(conn->error != CONNECTERR_NO_ERROR) 
    223     result = FALSE; 
    224  
    225   DisconnectFromHost(conn); 
    226  
    227   RETURN(result); 
    228   return result; 
     228  // wake up the calling thread if this is requested 
     229  if(isFlagSet(flags, DLURLF_SIGNAL)) 
     230    WakeupThread(NULL); 
     231 
     232  RETURN(success); 
     233  return success; 
    229234} 
    230235 
  • trunk/src/tcp/http.h

    r4981 r5442  
    2929***************************************************************************/ 
    3030 
    31 // forward declarations 
    32 struct Connection; 
     31#define DLURLF_SIGNAL (1<<0) 
    3332 
    34 // prototypes 
    35 BOOL TR_DownloadURL(struct Connection *conn, const char *server, const char *request, const char *filename); 
     33BOOL DownloadURL(const char *server, const char *request, const char *filename, const ULONG flags); 
    3634 
    3735#endif /* HTTP_H */ 
Note: See TracChangeset for help on using the changeset viewer.