# opkhelper # lib/control # Functions for parsing control files. # # Copyright (C) 2012 Patrick "P. J." McDermott # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . [ -n "${_OH_CONTROL_SH}" ] && return 0 _OH_CONTROL_SH=true . @@LIBDIR@@/messages . @@LIBDIR@@/locale . @@LIBDIR@@/util # Constant global parameters: OH_CONTROL_SOURCE_FIELDS_REQUIRED='Maintainer' OH_CONTROL_SOURCE_FIELDS_OPTIONAL='Build-Depends Homepage' OH_CONTROL_BINARY_FIELDS_REQUIRED='Architecture Platform Priority Description' OH_CONTROL_BINARY_FIELDS_OPTIONAL='Essential Depends Recommends Suggests '\ 'Pre-Depends Conflicts Provides Replaces' OH_CONTROL_SOURCE_FIELD_MAINTAINER= OH_CONTROL_SOURCE_FIELD_BUILD_DEPENDS= OH_CONTROL_SOURCE_FIELD_HOMEPAGE= OH_CONTROL_BINARY_FIELD_ARCHITECTURE= OH_CONTROL_BINARY_FIELD_PLATFORM= OH_CONTROL_BINARY_FIELD_PRIORITY= OH_CONTROL_BINARY_FIELD_DESCRIPTION= OH_CONTROL_BINARY_FIELD_ESSENTIAL= OH_CONTROL_BINARY_FIELD_DEPENDS= OH_CONTROL_BINARY_FIELD_RECOMMENDS= OH_CONTROL_BINARY_FIELD_SUGGESTS= OH_CONTROL_BINARY_FIELD_PRE_DEPENDS= OH_CONTROL_BINARY_FIELD_CONFLICTS= OH_CONTROL_BINARY_FIELD_PROVIDES= OH_CONTROL_BINARY_FIELD_REPLACES= oh_control_parse_source() { _control_parse "${OH_SOURCE_DIR}/control" 'SOURCE' } oh_control_parse_binary() { _control_parse "${OH_SOURCE_DIR}/${1}.pkg/control" 'BINARY' } oh_control_gen_source() { _old_package="${OH_CONTROL_BINARY_FIELD_PACKAGE}" _old_version="${OH_BINARY_VERSION}" _old_architecture="${OH_CONTROL_BINARY_FIELD_ARCHITECTURE}" _old_recommends="${OH_CONTROL_BINARY_FIELD_RECOMMENDS}" _old_description="${OH_CONTROL_BINARY_FIELD_DESCRIPTION}" OH_CONTROL_BINARY_FIELD_PACKAGE="src:${OH_SOURCE}" OH_BINARY_VERSION="${OH_SOURCE_VERSION}" OH_CONTROL_BINARY_FIELD_ARCHITECTURE='all' OH_CONTROL_BINARY_FIELD_RECOMMENDS="${OH_CONTROL_SOURCE_FIELD_BUILD_DEPENDS}" OH_CONTROL_BINARY_FIELD_DESCRIPTION="${OH_SOURCE} source package" _control_gen 'SOURCE' \ "src:${OH_SOURCE}.control/control" "src:${OH_SOURCE}.data" OH_CONTROL_BINARY_FIELD_PACKAGE="${_old_package}" OH_BINARY_VERSION="${_old_version}" OH_CONTROL_BINARY_FIELD_ARCHITECTURE="${_old_architecture}" OH_CONTROL_BINARY_FIELD_RECOMMENDS="${_old_recommends}" OH_CONTROL_BINARY_FIELD_DESCRIPTION="${_old_description}" } oh_control_gen_binary() { _control_gen 'BINARY' \ "${1}.control/control" "${1}.data" } _control_parse() { _control="${1}" _type="${2}" _req=" $(eval echo \$\{OH_CONTROL_"${_type}"_FIELDS_REQUIRED\}) " _opt=" $(eval echo \$\{OH_CONTROL_"${_type}"_FIELDS_OPTIONAL\}) " _all="${_req}${_opt}" _got=' ' # Initialize fields. for _name in ${_all}; do _param="OH_CONTROL_${_type}_FIELD_$(echo "${_name}" | \ LC_CTYPE=C tr '[:lower:]-' '[:upper:]_')" eval "${_param}=" done _param= _line_nr=0 while IFS= read -r _line; do _line_nr=$(($_line_nr + 1)) if [ "${_line# }" = "${_line}" ]; then # "Name: Value" line. _name="${_line%%:*}" _value="${_line#*: }" if [ -z "${_name}" -o "${_name}" = "${_line}" \ -o -z "${_value}" ]; then # Badly formatted control field. _control_parse_error "${_control}" "${_line_nr}" \ "${oh_str_control_bad_nv}" continue fi if [ "${_all% ${_name} *}" = "${_all}" ]; then # Unknown field. _control_parse_error "${_control}" "${_line_nr}" \ "${oh_str_control_unknown_field}" \ "${_name}" else # Remove field from list of required fields. _req="$(echo "${_req}" | sed "s/${_name}//")" fi if [ "${_got% ${_name} }" != "${_got}" ]; then # Duplicate field. _control_parse_error "${_control}" "${_line_nr}" \ "${oh_str_control_duplicate_field}" \ "${_field}" else _got="${_got}${_field} " fi _param="OH_CONTROL_${_type}_FIELD_$(echo "${_name}" | \ LC_CTYPE=C tr '[:lower:]-' '[:upper:]_')" # Escape the value. _value="$(echo "${_value}" | sed "s/'/'\\\\''/g")" eval "${_param}='${_value}'" else # Continuation line. if [ -z "${_param}" ]; then # Expecting a "Name: Value" line. _control_parse_error "${_control}" "${_line_nr}" \ "${oh_str_control_found_continuation}" continue fi _value="${_line# }" _value="$(echo "${_value}" | sed "s/'/'\\\\''/g")" eval "${_param}='${_param} ${_value}'" fi done <"${_control}" _req="${_req## }" _req="${_req%% }" if [ -n "${_req}" ]; then # Missing required control fields. _control_parse_error "${_control}" 0 \ "${oh_str_control_missing_fields}" \ "$(echo "${_req}" | sed 's/ / /g' | \ sed "s/ /${oh_str_list_item_separator}/g")" fi } _control_parse_error() { _file="${1}" _line_nr="${2}" _error="${3}" shift 3 if [ "${_line_nr}" -eq 0 ]; then _file_info=$(printf '%20s:' "${_file}") else _file_info=$(printf '%20s(l%d):' "${_file}" "${_line_nr}") fi oh_warn "${_file_info} ${_error}" "${@}" } _control_gen() { _type="${1}" _control="${2}" _data="${3}" # TODO: Handle platforms and architectures like "any" and "any-linux-any". # Calculate installed size. # Don't use du, since that considers the allocated size of files, symbolic # links, and directories (i.e. actual file sizes plus the filesystem # overhead on the build system). # See the following for more information: # # # _sizes="$(find "${_data}" -type f -exec wc -c '{}' ';' | cut -d ' ' -f 1)" _inst_size=0 for _size in ${_sizes}; do _inst_size=$(($_inst_size + $_size)) done # Convert bytes to kibibytes and round up. # Note: There is an inconsistency between the Debian Policy Manual and opkg # in the units of this field. Debian Policy defines this field in units of # kibibytes: # The disk space is given as the integer value of the estimated installed # size in bytes, divided by 1024 and rounded up. # However, opkg apparently attempts to convert this value from bytes to # kibibytes in its determination of whether the package's data will fit on # the system: # pkg_size_kbs = (pkg->installed_size + 1023)/1024; # TODO: Further investigate opkg's disk space calculation and, if necessary, # patch opkg and submit a bug report. _inst_size=$((($_inst_size + 1023) / 1024)) mkdir -p "${_control%/*}" cat >"${_control}" <>"${_control}" fi done cat >>"${_control}" <>"${_control}" fi }