github.com/containers/podman/v4@v4.9.4/pkg/specgen/generate/config_common.go (about)

     1  //go:build !remote
     2  // +build !remote
     3  
     4  package generate
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  )
    10  
    11  // ParseDevice parses device mapping string to a src, dest & permissions string
    12  func ParseDevice(device string) (string, string, string, error) {
    13  	var src string
    14  	var dst string
    15  	permissions := "rwm"
    16  	arr := strings.Split(device, ":")
    17  	switch len(arr) {
    18  	case 3:
    19  		if !IsValidDeviceMode(arr[2]) {
    20  			return "", "", "", fmt.Errorf("invalid device mode: %s", arr[2])
    21  		}
    22  		permissions = arr[2]
    23  		fallthrough
    24  	case 2:
    25  		if IsValidDeviceMode(arr[1]) {
    26  			permissions = arr[1]
    27  		} else {
    28  			if len(arr[1]) > 0 && arr[1][0] != '/' {
    29  				return "", "", "", fmt.Errorf("invalid device mode: %s", arr[1])
    30  			}
    31  			dst = arr[1]
    32  		}
    33  		fallthrough
    34  	case 1:
    35  		src = arr[0]
    36  	default:
    37  		return "", "", "", fmt.Errorf("invalid device specification: %s", device)
    38  	}
    39  
    40  	if dst == "" {
    41  		dst = src
    42  	}
    43  	return src, dst, permissions, nil
    44  }
    45  
    46  // IsValidDeviceMode checks if the mode for device is valid or not.
    47  // IsValid mode is a composition of r (read), w (write), and m (mknod).
    48  func IsValidDeviceMode(mode string) bool {
    49  	var legalDeviceMode = map[rune]bool{
    50  		'r': true,
    51  		'w': true,
    52  		'm': true,
    53  	}
    54  	if mode == "" {
    55  		return false
    56  	}
    57  	for _, c := range mode {
    58  		if !legalDeviceMode[c] {
    59  			return false
    60  		}
    61  		legalDeviceMode[c] = false
    62  	}
    63  	return true
    64  }