/******************************************************************** * FUNCTION read_txid_file * * Read the transaction ID file and return the current ID value found * * INPUTS: * txidfile == full filespec of the transaction ID file * curid == address of return ID * * OUTPUTS: * *curid == return current ID (if return NO_ERR * * RETURNS: * status *********************************************************************/ static status_t read_txid_file (const xmlChar *txidfile, cfg_transaction_id_t *curid) { assert( txidfile && "txidfile is NULL" ); assert( curid && "curid is NULL" ); *curid = 0; status_t res = NO_ERR; FILE *fil = fopen((const char *)txidfile, "r"); if (!fil) { res = errno_to_status(); log_error("\nError: Open txid file for read failed (%s)", get_error_string(res)); return res; } char buffer [128]; if (fgets(buffer, sizeof buffer, fil)) { /* expecting just 1 line containing the ASCII encoding of * the transaction ID */ log_debug4("\nRead transaction ID line '%s'", buffer); uint32 len = xml_strlen((const xmlChar *)buffer); if (len > 1) { /* strip ending newline */ buffer[len-1] = 0; ncx_num_t num; ncx_init_num(&num); res = ncx_convert_num((xmlChar *)buffer, NCX_NF_DEC, NCX_BT_UINT64, &num); if (res == NO_ERR) { agt_cfg_txid = num.ul; *curid = num.ul; log_debug3("\nGot transaction ID line '%llu'", (unsigned long long)num.ul); } else { log_error("\nError: txid is not valid (%s)", get_error_string(res)); } ncx_clean_num(NCX_BT_UINT64, &num); } else { res = ERR_NCX_INVALID_NUM; log_error("\nError: txid is not valid (%s)", get_error_string(res)); } } else { res = errno_to_status(); log_error("\nError: Read txid file failed (%s)", get_error_string(res)); } fclose(fil); return res; } /* read_txid_file */
/******************************************************************** * FUNCTION send_buff * * Send the buffer to the ncxserver * * This function is used by applications which do not * select for write_fds, and may not block (if fnctl used) * * INPUTS: * fd == the socket to write to * buffer == the buffer to write * cnt == the number of bytes to write * * RETURNS: * status *********************************************************************/ status_t send_buff (int fd, const char *buffer, size_t cnt) { size_t sent, left; ssize_t retsiz; uint32 retry_cnt; retry_cnt = 1000; sent = 0; left = cnt; while (sent < cnt) { retsiz = write(fd, buffer, left); if (retsiz < 0) { switch (errno) { case EAGAIN: case EBUSY: if (--retry_cnt) { break; } /* else fall through */ default: return errno_to_status(); } } else { sent += (size_t)retsiz; buffer += retsiz; left -= (size_t)retsiz; } } return NO_ERR; } /* send_buff */
/******************************************************************** * FUNCTION write_txid_file * * Write the transaction ID file with the supplied value * * INPUTS: * txidfile == full filespec of the transaction ID file * curid == pointer to new txid to write * * RETURNS: * status *********************************************************************/ static status_t write_txid_file (const xmlChar *txidfile, cfg_transaction_id_t *curid) { assert( txidfile && "txidfile is NULL" ); assert( curid && "curid is NULL" ); status_t res = NO_ERR; FILE *fil = fopen((const char *)txidfile, "w"); if (!fil) { res = errno_to_status(); log_error("\nError: Opening txid file (%s) for write failed (%s)", (const char *)txidfile, get_error_string(res)); return res; } uint32 len = 0; char buffer [128]; ncx_num_t num; ncx_init_num(&num); num.ul = *curid; res = ncx_sprintf_num((xmlChar *)buffer, &num, NCX_BT_UINT64, &len); if (res == NO_ERR) { buffer[len] = '\n'; buffer[len+1] = 0; int ret = fputs(buffer, fil); if (ret <= 0) { res = errno_to_status(); log_error("\nError: write txid ID file failed (%s)", get_error_string(res)); } } else { log_error("\nError: sprintf txid ID failed (%s)", get_error_string(res)); } ncx_clean_num(NCX_BT_UINT64, &num); fclose(fil); return res; } /* write_txid_file */
/******************************************************************** * FUNCTION save_aliases * * Save the aliases to the specified filespec * * INPUT: * fspec == output filespec to use (NULL == default) * * RETURNS: * status *********************************************************************/ status_t save_aliases (const xmlChar *fspec) { if (fspec == NULL) { fspec = get_aliases_file(); } status_t res = NO_ERR; xmlChar *fullspec = ncx_get_source(fspec, &res); if (res != NO_ERR) { log_error("\nError: Expand source '%s' failed (%s)\n", fspec, get_error_string(res)); return res; } res = check_for_saving_def_yangcli_file (ALIASES_FILE, fullspec); if (res != NO_ERR) { m__free(fullspec); return res; } FILE *fp = fopen((const char *)fullspec, "w"); if (fp) { /* this will truncate the file if there are no aliases */ alias_cb_t *alias; for (alias = get_first_alias(); alias != NULL; alias = get_next_alias(alias)) { write_alias(fp, alias); } /* Save mtime of this aliases file */ res = update_def_yangcli_file_mtime (ALIASES_FILE, fullspec); fclose(fp); } else { res = errno_to_status(); log_error("\nError: Open aliases file '%s' failed (%s)\n", fullspec, get_error_string(res)); } m__free(fullspec); return res; } /* save_aliases */