CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
                        const char *file)
{
  struct Curl_llist_element *e;
  struct Curl_llist_element *n;
  CURLcode result = CURLE_OK;
  FILE *out;
  char *tempstore;
  unsigned char randsuffix[9];

  if(!h)
    /* no cache activated */
    return CURLE_OK;

  /* if no new name is given, use the one we stored from the load */
  if(!file && h->filename)
    file = h->filename;

  if((h->flags & CURLHSTS_READONLYFILE) || !file || !file[0])
    /* marked as read-only, no file or zero length file name */
    goto skipsave;

  if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
    return CURLE_FAILED_INIT;

  tempstore = aprintf("%s.%s.tmp", file, randsuffix);
  if(!tempstore)
    return CURLE_OUT_OF_MEMORY;

  out = fopen(tempstore, FOPEN_WRITETEXT);
  if(!out)
    result = CURLE_WRITE_ERROR;
  else {
    fputs("# Your HSTS cache. https://curl.se/docs/hsts.html\n"
          "# This file was generated by libcurl! Edit at your own risk.\n",
          out);
    for(e = h->list.head; e; e = n) {
      struct stsentry *sts = e->ptr;
      n = e->next;
      result = hsts_out(sts, out);
      if(result)
        break;
    }
    fclose(out);
    if(!result && Curl_rename(tempstore, file))
      result = CURLE_WRITE_ERROR;

    if(result)
      unlink(tempstore);
  }
  free(tempstore);
  skipsave:
  if(data->set.hsts_write) {
    /* if there's a write callback */
    struct curl_index i; /* count */
    i.total = h->list.size;
    i.index = 0;
    for(e = h->list.head; e; e = n) {
      struct stsentry *sts = e->ptr;
      bool stop;
      n = e->next;
      result = hsts_push(data, &i, sts, &stop);
      if(result || stop)
        break;
      i.index++;
    }
  }
  return result;
}
CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
                        const char *file)
{
  struct Curl_llist_element *e;
  struct Curl_llist_element *n;
  CURLcode result = CURLE_OK;
  FILE *out;
  char *tempstore;
  unsigned char randsuffix[9];

  if(!h)
     
    return CURLE_OK;

   
  if(!file && h->filename)
    file = h->filename;

  if((h->flags & CURLHSTS_READONLYFILE) || !file || !file[0])
     
    goto skipsave;

  if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
    return CURLE_FAILED_INIT;

  tempstore = aprintf("%s.%s.tmp", file, randsuffix);
  if(!tempstore)
    return CURLE_OUT_OF_MEMORY;

  out = fopen(tempstore, FOPEN_WRITETEXT);
  if(!out)
    result = CURLE_WRITE_ERROR;
  else {
    fputs("# Your HSTS cache. https://curl.se/docs/hsts.html\n"
          "# This file was generated by libcurl! Edit at your own risk.\n",
          out);
    for(e = h->list.head; e; e = n) {
      struct stsentry *sts = e->ptr;
      n = e->next;
      result = hsts_out(sts, out);
      if(result)
        break;
    }
    fclose(out);
    if(!result && Curl_rename(tempstore, file))
      result = CURLE_WRITE_ERROR;

    if(result)
      unlink(tempstore);
  }
  free(tempstore);
  skipsave:
  if(data->set.hsts_write) {
     
    struct curl_index i;  
    i.total = h->list.size;
    i.index = 0;
    for(e = h->list.head; e; e = n) {
      struct stsentry *sts = e->ptr;
      bool stop;
      n = e->next;
      result = hsts_push(data, &i, sts, &stop);
      if(result || stop)
        break;
      i.index++;
    }
  }
  return result;
}