/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2013 Thomas Schmitt Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include /* ts A61008 */ /* #include */ #include #include #include #include #include #include #include /* ts A80914 : This is unneeded. Version info comes from libburn.h. #include "v ersion.h" */ #include "util.h" #include "libburn.h" void burn_version(int *major, int *minor, int *micro) { /* ts A80408 : switched from configure.ac versioning to libburn.h versioning */ *major = burn_header_version_major; *minor = burn_header_version_minor; *micro = burn_header_version_micro; } struct cd_mid_record { char *manufacturer; int m_li; int s_li; int f_li; char *other_brands; }; typedef struct cd_mid_record cd_mid_record_t; /* ts A90902 */ /** API @param flag Bitfield for control purposes, bit0= append "(aka %s)",other_brands to reply */ char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li, int m_lo, int s_lo, int f_lo, int flag) { static cd_mid_record_t mid_list[]= { {"SKC", 96, 40, 0, ""}, {"Ritek Corp" , 96, 43, 30, ""}, {"TDK / Ritek" , 97, 10, 0, "TRAXDATA"}, {"TDK Corporation" , 97, 15, 0, ""}, {"Ritek Corp" , 97, 15, 10, "7-plus, Aopen, PONY, Power Source, TDK, TRAXDATA, HiCO, PHILIPS, Primdisc, Victor.JVC, OPTI STORAGE, Samsung"}, {"Mitsubishi Chemical Corporation" , 97, 15, 20, ""}, {"Nan-Ya Plastics Corporation" , 97, 15, 30, "Hatron, MMore, Acer, LITEON"}, {"Delphi" , 97, 15, 50, ""}, {"Shenzhen SG&SAST" , 97, 16, 20, ""}, {"Moser Baer India Limited" , 97, 17, 0, "EMTEC, Intenso, YAKUMO, PLATINUM, Silver Circle"}, {"SKY media Manufacturing SA" , 97, 17, 10, ""}, {"Wing" , 97, 18, 10, ""}, {"DDT" , 97, 18, 20, ""}, {"Daxon Technology Inc. / Acer" , 97, 22, 60, "Maxmax, Diamond Data, BenQ, gold, SONY"}, {"Taiyo Yuden Company Limited" , 97, 24, 0, "Maxell, FUJIFILM, SONY"}, {"Sony Corporation" , 97, 24, 10, "LeadData, Imation"}, {"Computer Support Italcard s.r.l" , 97, 24, 20, ""}, {"Unitech Japan Inc." , 97, 24, 30, ""}, {"MPO, France" , 97, 25, 0, "TDK"}, {"Hitachi Maxell Ltd." , 97, 25, 20, ""}, {"Infodisc Technology Co,Ltd." , 97, 25, 30, "MEMOREX, SPEEDA, Lead data"}, {"Xcitec" , 97, 25, 60, ""}, {"Fornet International Pte Ltd" , 97, 26, 0, "COMPUSA, Cdhouse"}, {"Postech Corporation" , 97, 26, 10, "Mr.Platinum"}, {"SKC Co Ltd." , 97, 26, 20, "Infinite"}, {"Fuji Photo Film Co,Ltd." , 97, 26, 40, ""}, {"Lead Data Inc." , 97, 26, 50, "SONY, Gigastorage, MIRAGE"}, {"CMC Magnetics Corporation" , 97, 26, 60, "Daxon, Verbatim, Memorex, Bi-Winner, PLEXTOR, YAMAHA, Melody, Office DEPOT, Philips, eMARK, imation, HyperMedia, Samsung, Shintaro, Techworks"}, {"Ricoh Company Limited" , 97, 27, 0, "Sony, Digital Storage, Csita"}, {"Plasmon Data Systems Ltd" , 97, 27, 10, "Ritek, TDK, EMTEC, ALPHAPET, MANIA"}, {"Princo Corporation" , 97, 27, 20, ""}, {"Pioneer" , 97, 27, 30, ""}, {"Eastman Kodak Company" , 97, 27, 40, ""}, {"Mitsui Chemicals Inc." , 97, 27, 50, "MAM-A, TDK"}, {"Ricoh Company Limited" , 97, 27, 60, "Ritek"}, {"Gigastorage Corporation" , 97, 28, 10, "MaxMax, Nan-Ya"}, {"Multi Media Masters&Machinary SA" , 97, 28, 20, "King, Mmirex"}, {"Ritek Corp" , 97, 31, 0, "TDK"}, {"Grand Advance Technology Sdn. Bhd." , 97, 31, 30, ""}, {"TDK Corporation" , 97, 32, 00, ""}, {"Prodisc Technology Inc." , 97, 32, 10, "Smartbuy, Mitsubishi, Digmaster, LG, Media Market"}, {"Mitsubishi Chemical Corporation" , 97, 34, 20, "YAMAHA, Verbatim"}, {"Mitsui Chemicals Inc." , 97, 48, 50, ""}, {"TDK Corporation" , 97, 49, 0, ""}, {"", 0, 0, 0, ""} }; int i, f_li_0; char buf[1024]; char *result = NULL; if (m_li == 0 && s_li == 2 && f_li == 0) { result = strdup("(no manufacturer code)"); return result; } f_li_0 = f_li - (f_li % 10); for (i = 0; mid_list[i].manufacturer[0]; i++) { if (m_li == mid_list[i].m_li && s_li == mid_list[i].s_li && (f_li_0 == mid_list[i].f_li || f_li == mid_list[i].f_li)) break; } if (mid_list[i].manufacturer[0] == 0) { sprintf(buf, "Unknown CD manufacturer. Please report code '%2.2dm%2.2ds%2.2df/%2.2dm%2.2ds%2.2df', the human readable brand, size, and speed to scdbackup@gmx.net.", m_li, s_li, f_li, m_lo, s_lo, f_lo); result = strdup(buf); return result; } /* Compose, allocate and copy result */ if ((flag & 1) && mid_list[i].other_brands[0]) { sprintf(buf, "%s (aka %s)", mid_list[i].manufacturer, mid_list[i].other_brands); result = strdup(buf); } else result = strdup(mid_list[i].manufacturer); return result; } /* ts A90904 */ struct dvd_mid_record { char *mc1; int mc1_sig_len; char *manufacturer; }; typedef struct dvd_mid_record dvd_mid_record_t; /* ts A90904 */ char *burn_guess_manufacturer(int prf, char *media_code1, char *media_code2, int flag) { int i, l = 0, m_li, s_li, f_li, m_lo, s_lo, f_lo; char buf[1024]; char *result = NULL, *cpt; /* Important Note: media_code1 and media_code2 are supposed to be encoded by burn_util_make_printable_word(). Especially: ' ' -> '_' , {"_%/" unprintables -> %XY) */ static dvd_mid_record_t mid_list[]= { {"AML", 8, "UML"}, {"BeAll", 5, "BeAll Developers, Inc."}, {"CMC", 3, "CMC Magnetics Corporation"}, {"DAXON", 5, "Daxon Technology Inc. / Acer"}, {"Daxon", 5, "Daxon Technology Inc. / Acer"}, {"FUJI", 4, "Fujifilm Holdings Corporation"}, {"INFODISC", 8, "New Star Digital Co., Ltd."}, {"INFOME", 6, "InfoMedia Inc."}, {"ISMMBD", 6, "Info Source Multi Media Ltd."}, {"JVC", 3, "JVC Limited"}, {"KIC01RG", 7, "AMC"}, {"LD", 8, "Lead Data Inc."}, {"LGE", 3, "LG Electronics"}, {"MAM", 8, "Mitsui Advanced Media, Inc. Europe"}, {"MAXELL", 6, "Hitachi Maxell Ltd."}, {"MBI", 3, "Moser Baer India Limited"}, {"MCC", 8, "Mitsubishi Chemical Corporation"}, {"MCI", 8, "Mitsui Chemicals Inc."}, {"MEI", 3, "Panasonic Corporation"}, {"MILLEN", 8, "Millenniata Inc."}, {"MKM", 3, "Mitsubishi Kagaku Media Co."}, {"MMC", 8, "Mitsubishi Kagaku Media Co."}, {"MXL", 8, "Hitachi Maxell Ltd."}, {"NANYA", 5, "Nan-Ya Plastics Corporation"}, {"NSD", 8, "NESA International Inc."}, {"OPTODISC", 8, "Optodisc Technology Corporation"}, {"OTCBDR", 8, "Optodisc Technology Corporation"}, {"PHILIP", 8, "Moser Baer India Limited"}, {"PHILIPS", 8, "Philips"}, {"PRINCO", 6, "Princo Corporation"}, {"PRODISC", 7, "Prodisc Technology Inc."}, {"Prodisc", 7, "Prodisc Technology Inc."}, {"PVC", 3, "Pioneer"}, {"RICOHJPN", 8, "Ricoh Company Limited"}, {"RITEK", 5, "Ritek Corp"}, {"SONY", 4, "Sony Corporation"}, {"TDK", 3, "TDK Corporation"}, {"TTG", 3, "TDK Corporation"}, {"TTH", 3, "TDK Corporation"}, {"TY", 8, "Taiyo Yuden Company Limited"}, {"TYG", 3, "Taiyo Yuden Company Limited"}, {"UME", 3, "UmeDisc Limited"}, {"UTJR001", 7, "Unifino Inc."}, {"VERBAT", 5, "Mitsubishi Kagaku Media Co."}, {"YUDEN", 5, "Taiyo Yuden Company Limited"}, {"", 0, ""} }; if (media_code2 != NULL && (prf == -1 || prf == 0x09 || prf == 0x0A)) { if (strlen(media_code2) == 9 && media_code1[0] == '9' && media_code1[2] == 'm' && media_code1[5] == 's' && media_code1[8] == 'f' && strchr(media_code1, '%') == NULL) { sscanf(media_code1, "%dm%ds%df", &m_li, &s_li, &f_li); sscanf(media_code2, "%dm%ds%df", &m_lo, &s_lo, &f_lo); if (m_li >= 96 && m_li <= 97 && m_lo > 0) { result = burn_guess_cd_manufacturer( m_li, s_li, f_li, m_lo, s_lo, f_lo, 0); return result; } } } /* DVD-R do not keep manufacturer id apart from media id. Some manufacturers use a blank as separator which would now be '_'. */ cpt = strchr(media_code1, '_'); if (cpt != NULL && (prf == -1 || prf == 0x11 || prf == 0x13 || prf == 0x14 || prf == 0x15)) l = cpt - media_code1; for (i = 0; mid_list[i].mc1[0]; i++) { if (strncmp(mid_list[i].mc1, media_code1, mid_list[i].mc1_sig_len) == 0) break; if (l > 0) if (strncmp(mid_list[i].mc1, media_code1, l) == 0) break; } if (mid_list[i].mc1[0] == 0) { sprintf(buf, "Unknown DVD/BD manufacturer. Please report code '%s/%s', the human readable brand, size, and speed to scdbackup@gmx.net.", media_code1, media_code2); result = strdup(buf); return result; } result = strdup(mid_list[i].manufacturer); return result; } /* ts A90905 */ /* Make *text a single printable word */ /* IMPORTANT: text must be freeable memory ! @param flag bit0=escape '/' too bit1=(overrides bit0) do not escape " _/" */ int burn_util_make_printable_word(char **text, int flag) { int i, esc_add = 0, ret; char *wpt, *rpt, *new_text = NULL; if (flag & 2) flag &= ~1; for (i = 0; (*text)[i]; i++) { rpt = (*text) + i; if (*rpt < 32 || *rpt > 126 || *rpt == 96 || ((*rpt == '_' || *rpt == '%') && (!(flag & 2))) || (*rpt == '/' && (flag & 1))) esc_add += 2; } if (esc_add) { new_text = calloc(strlen(*text) + esc_add + 1, 1); if (new_text == NULL) { ret = -1; goto ex; } wpt = new_text; for (i = 0; (*text)[i]; i++) { rpt = (*text) + i; if (*rpt < 32 || *rpt > 126 || *rpt == 96 || ((*rpt == '_' || *rpt == '%') && (!(flag & 2))) || (*rpt == '/' && (flag & 1))) { sprintf(wpt, "%%%2.2X", (unsigned int) *((unsigned char *) rpt)); wpt+= 3; } else *(wpt++) = *rpt; } *wpt = 0; free(*text); *text = new_text; } if (!(flag & 2)) for (i = 0; (*text)[i]; i++) if ((*text)[i] == ' ') (*text)[i] = '_'; ret = 1; ex: return ret; } /* ts B11216 */ /** Read a line from fp and strip LF or CRLF */ char *burn_sfile_fgets(char *line, int maxl, FILE *fp) { int l; char *ret; ret = fgets(line, maxl, fp); if (ret == NULL) return NULL; l = strlen(line); if (l > 0) if (line[l - 1] == '\r') line[--l] = 0; if (l > 0) if (line[l - 1] == '\n') line[--l] = 0; if(l > 0) if(line[l - 1] == '\r') line[--l] = 0; return ret; } char *burn_printify(char *msg) { char *cpt; for (cpt = msg; *cpt != 0; cpt++) if (*cpt < 32 || *cpt > 126) *cpt = '#'; return msg; } /* ts B30521 */ void burn_int_to_lsb(int val, char *target) { unsigned char *buf; buf = (unsigned char *) target; buf[0] = val & 0xff; buf[1] = (val >> 8) & 0xff; buf[2] = (val >> 16) & 0xff; buf[3] = (val >> 24) & 0xff; } /* ts B30609 */ double burn_get_time(int flag) { int ret; struct timeval tv; #ifdef Libburn_use_clock_gettime_monotoniC #ifdef _POSIX_TIMERS #ifdef _POSIX_MONOTONIC_CLOCK /* Enable by export CFLAGS=-DLibburn_use_clock_gettime_monotoniC export LIBS=-lrt ./configure ... && make clean && make */ struct timespec tp; ret = clock_gettime(CLOCK_MONOTONIC, &tp); if (ret == 0) return ((double) tp.tv_sec) + ((double) tp.tv_nsec) * 1.0e-9; #endif /* _POSIX_MONOTONIC_CLOCK */ #endif /* _POSIX_TIMERS */ #endif /* Xorriso_use_clock_gettime_monotoniC */ ret = gettimeofday(&tv, NULL); if (ret == 0) return ((double) tv.tv_sec) + ((double) tv.tv_usec) * 1.0e-6; return (double) time(NULL); } /* ts B40609 */ off_t burn_sparse_file_addsize(off_t write_start, struct stat *stbuf) { off_t add_size; add_size = stbuf->st_blocks * (off_t) 512; if (add_size < stbuf->st_size) { /* Sparse file */ if (write_start < stbuf->st_size) { /* Might write into sparse gaps */ if (write_start > add_size) add_size = write_start; } else { /* Will not write into sparse area */ add_size = stbuf->st_size; } } return add_size; }